旧GCC 4.1.2 接受,新GCC 4.5.1 接受以下程序.
但它确实是正确的吗?该标准对于使用类型的模板参数声明构造函数的说法是什么?
(我觉得有趣的是我不允许在外线定义中做同样的事情.)
#include <iostream>
template <typename T>
struct Foo {
Foo<T>(); // <---
};
template <typename T>
Foo<T>::Foo() {
std::cout << ":)";
}
int main() {
Foo<int> f;
}
Run Code Online (Sandbox Code Playgroud)
我问的原因是,在这个答案的评论中提出GCC可能在这里出错.
我将把最近在圣诞节寄出的可能 DR 的邮件副本放在这里
下面的代码格式正确吗?
Run Code Online (Sandbox Code Playgroud)template<typename T> struct A { A<T>(); };我测试的几个编译器(clang、g++ 和 comeau conline)都接受这一点。事实上 12.1 并不禁止这个(
A<T>是该类的名称,而不是 typedef 名称),但 8.3p1 说出现在 declarator-id 中的 unqualified-id 应是一个简单标识符,除了一些特殊函数的声明 (12.3, 12.4, 13.5) ...
构造函数是一种特殊的成员函数,但交叉引用列表不包括 12.1。这是否意味着上面的代码格式错误?或者这是一个意外的遗漏?
如果您在外部定义中执行相同的操作,您将尝试将模板参数传递给构造函数。这是有效的代码
struct A {
template<typename T> A();
};
template<> A::A<int>() { }
Run Code Online (Sandbox Code Playgroud)
规范说,当在查找类的范围时在限定名称中使用注入的类名时(就像在 中一样A::A),那么当名称查找接受函数/构造函数名称时,注入的类名引用将被转换为解析到该类的构造函数(如果名称查找上下文仅接受类型,则该名称将保留注入的类名称,并将表示类类型)。之后A::A,名称查找完成并生成构造函数。然后只能将其<int>解析为模板参数列表。如果你的构造函数中没有模板,你的代码将是无效的。