c++ - 为什么 `typename` 仍然需要,即使模板类型声明为 `class`?

  显示原文与译文双语对照的内容
0 0

#include <type_traits>

using namespace std;

template<class T> struct IsCharType { enum { value = false }; }; 
template<> struct IsCharType<char> { enum { value = true }; }; 
template<> struct IsCharType<wchar_t> { enum { value = true }; };

template<class CharType, class = enable_if<IsCharType<CharType>::value>::type>
struct MyString
{
 MyString()
 {}

 MyString(CharType*)
 {}
};

template<class CharType>
MyString<CharType> GetMyString(CharType* str)//error C2923
{
 return MyString<CharType>(str);
}

int main()
{}

我的编译器是 VC++ 2013 RC 。 无法编译上面的代码,因为C2923错误。

错误 C2923:'mystring':'enable_if:::: 值,void> :: type'不是参数''的有效模板类型参数'

但是如果我改变


template<class CharType, class = enable_if<IsCharType<CharType>::value>::type>


template<class CharType, class = typename enable_if<IsCharType<CharType>::value>::type>

那就行了。

我只是想知道为什么 typename 在这里是必需的? 在本例中,我有两个原因:

  1. 如果第二个模板参数是一个类型名称,编译器可以推断出它,因为我将它作为。

  2. 即使编译器是类型名,如果是 SFINAE 规则,编译器不应该失败,因为模板函数 GetMyString 不被调用。

时间: 原作者:

0 0

你还没有将它的声明为类。 模板参数声明


class = enable_if<IsCharType<CharType>::value>::type

是未命名类型参数的声明。 我们可以给这个参数一个明确的名称,e.g.


class U = enable_if<IsCharType<CharType>::value>::type

因此在这种情况下,U 被声明为类型参数("作为类") 。

同时,= 右边的一切都不是"声明为类"。 编译器按照常规规则进行解释,不考虑类型参数的默认参数。

像"由于这是用户定义类型参数的默认参数,所以编译器必须自己实现这是一个类型"这样的逻辑并不适用于这里,因为语言规范并没有说它。 此外,语言标准实际上说

在模板声明或者定义中使用的名称假定不是用模板参数命名类型,除非名称查找找到类型名。

这意味着,编译器是不需要的,假定它是


enable_if<IsCharType<CharType>::value>::type

它不是一种类型,与你期望它做的相反。

语言确实有许多上下文,其中依赖名无条件地假定为命名类型。 包括构造函数初始值设定项列表,基类说明符和详细类型说明符。 但是模板类型参数的默认参数不是这样的上下文之一。

SFINAE在这里不保存这里情况。 SFINAE,顾名思义,在替换时工作。 你的代码永远不会被替换,它会破坏很多。 它只是一个无效的模板定义。

原作者:
...