在Where in the C++11 standard does it prohibit 'template <typename T> class A {...}; template <typename T> class A<int> {...};' (if anywhere)? ,已确认 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;
};
在完全理解上述语法不代表有效的 C++ 的情况下,我仍然可以想象上述代码片段在语法上的明确用法,如下所示:
A<float> a1;
A<int><double> a2;
a1.t = 2.0f;
a2.i = 2;
a2.t = 2.0;
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.
现在让我们尝试在其他模板中使用它。考虑
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?
还不算太糟;编译器可能会对此提示。不过,我认为我们开始看到这有点奇怪。好吧,把它提高一个档次:
template<template<typename> class A> struct Foo { ... };
Foo<A> f; // this would usually work, does it now?
如果您回答否,如果在编译时不知道特化怎么办?
编辑:稍微扩展一下,考虑一个我喜欢称之为包特征的模板-模板参数的真实场景:
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;
并提供类似 A
的内容,它是除 int
之外的所有内容的类和 int
的类模板。然后努力锻炼
applies_to_all<A, double, float, std::string, int>::value
请注意,这个简单的案例不是您可能看到的代码。你真正得到的是这些东西在其他模板中嵌套了三个层次,看起来像这样:
applies_to_all<A, T...>::value
可能可以为此定义一种在数学上一致的行为,但我怀疑是否可以定义有用的行为。当然,它不符合 POLA。
按照这些思路,您可能会想到更多。以这种方式模糊类和类模板之间的界限势必会破坏各种东西。
关于c++ - 为什么不能在全特化中引入新的模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27504121/