第1章 函数模板:1.4 默认模板参数

1.4 Default Template Arguments

1.4 默认模板参数

You can also define default values for template parameters. These values are called default template arguments and can be used with any kind of template. They may even refer to previous template parameters.

你还可以定义模板参数的默认值。这些值被称为默认模板参数,它们可以与任何类型的模板一起使用。默认模板参数甚至可以引用在它之前声明的模板参数。(译者注:这里的任何类型模板如类模板或函数模板,没错,函数模板也可以用了)

For example, if you want to combine the approaches to define the return type with the ability to have multiple parameter types (as discussed in the section before), you can introduce a template parameter RT for the return type with the common type of the two arguments as default. Again, we have multiple options:

例如,如果要结合使用多个参数类型的方法来定义返回类型(如前一节所述)。则可以为返回类型引入模板参数RT,并将两个参数的公共类型作为默认参数。同样,我们有多种选择:

1. We can use operator?: directly. However, because we have to apply operator?: before the call parameters a and b are declared, we can only use their types:

1.可以直接使用“?:”运算符。但是,由于我们需要在声明形参a和b之前使用“?:”运算符,所以目前只能使用它们的类型。

#include <type_traits>

template<typename T1, typename T2,
               typename RT = std::decay_t<decltype(true ? T1() :T2())>>

RT max (T1 a, T2 b)
{
    return b < a ? a : b;
}

Note again the usage of std::decay_t<> to ensure that no reference can be returned.

注意,std::decay_t<>的使用是为了确保不会返回引用类型

Note also that this implementation requires that we are able to call default constructors for the passed types. There is another solution, using std::declval, which, however, makes the declaration even more complicated. See Section 11.2.3 on page 166 for an example.

还要注意,这个实现要求我们可以调用传入类型的默认构造函数。这里有另一种解决方案,使用std::declval,但这会使得声明变得更加复杂。可以参考第166页的11.2.3节。

2. We can also use the std::common_type<> type trait to specify the default value for the return type:

2. 也可以使用std::common_type<>类型萃取来指定默认的返回类型。

#include <type_traits>

template<typename T1, typename T2,
               typename RT = std::common_type_t<T1,T2>>
RT max (T1 a, T2 b)
{
    return b < a ? a : b;
}

 

Again, note that std::common_type<> decays so that the return value can’t become a reference.

同样,请注意std::common_type<>也会退化,因此返回类型不会是引用类型。

In all cases, as a caller, you can now use the default value for the return type:

作为调用者,现在在任何情况下都可以使用返回类型的默认值。

auto a = ::max(4, 7.2);

or specify the return type after all other argument types explicitly:

或者,在所有其他参数类型之后显式指定返回类型:

auto b = ::max<double,int,long double>(7.2, 4);

However, again we have the problem that we have to specify three types to be able to specify the return type only. Instead, we would need the ability to have the return type as the first template parameter, while still being able to deduce it from the argument types. In principle, it is possible to have default arguments for leading function template parameters even if parameters without default arguments follow:

但是,同样的问题是,我们必须指定三种类型才能指定返回类型。相反,我们可能需要一种将返回类型作为第一个模板参数,但仍可以从参数类型中将它的类型推导出来的能力。原则上,即使不带默认模板参数,也可以为前导的函数模板参数设置默认类型。(译者注:假设函数模板共有N个参数,调用时可以为第1个至第k个参数设置默认类型。称这k个参数称为前导参数。如func<int,float,string>(5, 4)中,有3个前导模板参数。)

template<typename RT = long, typename T1, typename T2>
RT max (T1 a, T2 b)
{
    return b < a ? a : b;
}

 

With this definition, for example, you can call:

例如,根据这个定义,你可以调用:

int i;
long l;
…
max(i, l);   // returns long (default argument of template parameter for return type)
max<int>(4, 42); // returns int as explicitly requested

However, this approach only makes sense, if there is a “natural” default for a template parameter. Here, we need the default argument for the template parameter to depend from previous template parameters. In principle, this is possible as we discuss in Section 26.5.1 on page 621, but the technique depends on type traits and complicates the definition.

但是,这种方法只有在模板参数存在“自然”默认值时才有意义。在这里,我们需要的模板参数的默认类型依赖于其之前的模板参数。原则上,这是可能的,正如我们在第621页的26.5.1节中所讨论的那样,但是该技术依赖于类型萃取,而且会使定义变得更加复杂。

For all these reasons, the best and easiest solution is to let the compiler deduce the return type as proposed in Section 1.3.2 on page 11.

基于以上这些原因,最好和最简单的解决方案是让编译器根据第11页的1.3.2节建议推导返回类型。

猜你喜欢

转载自www.cnblogs.com/5iedu/p/12696602.html
今日推荐