Dan*_*aum 3 c++ templates language-lawyer c++11
在C++ 11标准中的位置它禁止'template <typename T> class A {...}; template <typename T> class A <int> {...};' (如果有的话)?,已经确认在C++ 11标准中不允许使用以下语法:
/* invalid C++ */
template <typename T>
class A
{
public:
T t;
};
// phony "full specialization" that mistakenly attempts
// to introduce a *new* template parameter
template <typename T>
class A<int>
{
public:
int i;
T t;
};
Run Code Online (Sandbox Code Playgroud)
完全理解上面的语法并不代表有效的C++,但我可以想象一下语法上明确使用上面的代码片段,如下所示:
A<float> a1;
A<int><double> a2;
a1.t = 2.0f;
a2.i = 2;
a2.t = 2.0;
Run Code Online (Sandbox Code Playgroud)
对于C++来说,支持上面的语法似乎在语法上和语义上都是明确的.
(如果任何人都不清楚预期的语义,请发表评论,我会解释.)
我会将此语法描述为"在完全专业化中引入新模板参数".
在这个被修改为支持上述语法和语义的C++编译器的想象场景中,编译器将看到A<int> a2;并识别出尝试的实例化与主模板匹配; 然后它将搜索特化并找到并选择完整的专业化A<int>(忽略<double>); 然后会注意到这个完整的特化引入了一个新的模板参数T,在声明的变量的情况下a2是一个double.
如果我说上面的语法和语义是明确的,那么我想知道为什么这不是C++的一部分.我可以想到三个原因,但也许答案是不同的或更复杂的.
我想知道为什么C++不支持这个 - 我是否正确我的一个要点提供了答案?
哦,这会以有趣的方式爆炸.
为清楚起见,我假设您的意思是使用您的示例代码,
A<double> a; // okay
A<int> a2; // not okay, A<int> is not a class but a class template.
Run Code Online (Sandbox Code Playgroud)
现在让我们尝试在其他模板中使用它.考虑
template<typename T>
void function<A<T> const &a) { ... }
A<double> a;
A<int><double> a2;
function(a); // that looks okay.
function(a2); // er...compiler error, I guess?
Run Code Online (Sandbox Code Playgroud)
那还不错; 编译器可能会抱怨这一点.我想我们已经开始看到这有点奇怪了.好吧,把它提升一个档次:
template<template<typename> class A> struct Foo { ... };
Foo<A> f; // this would usually work, does it now?
Run Code Online (Sandbox Code Playgroud)
如果你回答否,如果在编译时不知道专业化怎么办?
编辑:扩展这一点,考虑模板模板参数的真实场景,我喜欢调用包特征:
template<template<typename> class, typename...> struct applies_to_all;
template<template<typename> class predicate, typename T, typename... Pack>
struct applies_to_all<predicate, T, Pack...> {
static bool const value =
predicate<T>::value && applies_to_all<predicate, Pack...>::value;
};
template<template<typename> class predicate>
struct applies_to_all<predicate> {
static bool const value = true;
};
...
bool b = applies_to_all<std::is_integral, int, long, double>::value;
Run Code Online (Sandbox Code Playgroud)
并提供这样的东西A,这是一个类,除了int和一个类模板int.然后尝试解决
applies_to_all<A, double, float, std::string, int>::value
Run Code Online (Sandbox Code Playgroud)
请注意,这个简单的情况并不是您可能会看到的代码.你真正得到的是这些东西嵌套在其他模板的三个层次深处,它看起来像这样:
applies_to_all<A, T...>::value
Run Code Online (Sandbox Code Playgroud)
可能会为此定义一个在数学上一致的行为,但我怀疑可以定义一个有用的行为.当然它不符合POLA标准.
你可以在这些方面提出更多的建议.以这种方式模糊类和类模板之间的界限必将打破各种各样的东西.
| 归档时间: |
|
| 查看次数: |
235 次 |
| 最近记录: |