很好奇:在C ++ 17和更高版本中,我们可以为非类型模板参数使用auto
占位符:
template<typename A, auto B>
class C {
public:
A foo() { return B; }
};
但是我们可以代替模板类型参数auto
来代替A
吗?
example.cpp
template<typename A, A B>
class C {
public:
A foo() { return B; }
};
int main()
{
C<int, 5> c;
std::cout << c.foo() << std::endl;
return 0;
}
实际上,我们可以做到这一点,并且-std = c ++ 11的clang允许这样做。
$ g++ -std=c++11 example.cpp
$ ./a.out
5
那么标准呢?我没有为此找到任何明确的规则。 谢谢!
答案 0 :(得分:1)
模板参数可以分为:
1. Type parameters
2. Non type parameters
3. Template template parameters
在您的情况下,语句A B
是非类型模板参数,其类型是模板类型参数A
。
请记住,在您的示例中,您这样做:
return B;
上面的语句将在非A
的类型copy constructible
上失败(这很容易用一个概念表示)。
请牢记(如注释中所指出),C ++ 17强制执行复制省略。
答案 1 :(得分:1)
但是我们可以传递而不是定义在左侧的“自动”模板类型参数吗?
好的。这是旧方法。
但是auto
方式可以避免传递类型A
。
在C ++ 17中,您可以编写
template <auto B>
class C {
public:
auto foo() { return B; }
};
因此无需传递类型A
。
我不知道在C ++ 11 / C ++ 14中也可以做到这一点。
我的意思是:如果需要,在C ++ 11 / C ++ 14中将值传递给模板...如果类型是固定的,就没有问题
template <int I>
但是类型本身可以不同,在C ++ 11 / C ++ 14中,您必须先传递类型,然后再传递值,如您的example.cpp
template <typename T, T A>
旧的问题是,如果您要调用这种类型的模板,则必须多余,并写为
C<decltype(x), x> some_C_variable;
而我所知避免这种冗余的唯一方法是通过make函数(例如make_tuple()
)或C风格的宏。
在C ++ 17中,您可以简单地编写
C<x> some_C_variable
,并且在C模板类/结构内部,可以从x
获得decltype(B)
的类型。
对于C ++ 17标准参考...
首先,将auto
定义为“占位符”
从10.1.7.4(auto
说明符)开始,指向第1点
auto
和decltype(auto)
type-specifier 用于指定占位符类型,该占位符类型稍后将通过初始化程序的推导来替换。
在C ++ 11 / C ++ 14中也是如此
但是C ++ 17标准在第4点枚举中为“模板参数”(17.1)添加了新点4.6
- 非类型 template-parameter 必须具有以下(可选的cv限定)类型之一:
[...]
(4.6)包含占位符类型(10.1.7.4)的类型