c++ - 显式成员特化

标签 c++ templates language-lawyer explicit-specialization

g++ 3.4.5 接受此代码:

template <typename T> struct A
{
    static const char* const str;
};

struct B {};

typedef A<B> C;

template<> const char* const C::str = "B";
// Equivalent to following?
// template<> const char* const A<B>::str = "B";

但我不确定它是否真的合法 C++03。特别是,

[14.7p3] In an explicit specialization declaration for a class template, a member of a class template or a class member template, the name of the class that is explicitly specialized shall be a template-id.

这个要求是说在这个例子的最后必须使用非 typedef 版本吗?还是我误解了什么?

编辑:进一步证据:Defect Report 403建议将类型(在该上下文中,函数调用表达式的参数类型)说成 template-id 是不正确的,因为 template-id 有一个句法意义,而不是语义意义。标准的后续草案在 3.4.2 中使用了“类模板特化”而不是“template-id”。

这支持了这样的论点,尽管 A<B>C表示相同的类型(并且具有相同或几乎相同的语义),A<B>是一个 template-idC不是,因为术语 template-id 将句法内容称为标记序列,而不是这些标记的含义。

最佳答案

我认为这是严格的病式(至少根据 C++ '03)。

我的逻辑是,虽然 typedef (7.1.3/1):

... is thus a synonym for another type.

标准仍然明确允许在需要 class-name 的地方使用 typedef (7.1.3/4):

A typedef-name that names a class is a class-name

template-id 没有这样的词。

关于c++ - 显式成员特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4464300/

相关文章:

c++ - 在 GNU 的 C++ 代码中使用 C 头文件。包含内联程序集 : impossible constraint in 'asm' 的错误

templates - 如何更改 Mailchimp Wordpress 小部件的模板?

c++ - 为什么 MSVC 16.7 处理涉及从 long 到 int 不明确转换的函数重载?

c++ - 什么叫表达式 `T (&some(...)) [2]` where T=char

c++ - 为什么叫 "non-type"模板参数?

c++ - 全局和嵌套匿名命名空间中的歧义访问标识符

c++ - 按位运算符和符号类型

c++ - 了解 C++ 中的位字段打包

vector::push_back() 中的 C++ 奇怪行为

c++ - 使用 VS2013 express 在 Windows 8.1 上构建 cpprest (Casablanca)