我尝试使用模板专精化,以便我可以针对不同类型使用特殊行为。但是,我无法获得字符串文字类型(const char[N]
)的模板特化以绑定到专用模板。
我有一个简单的模板select_type<T>
,具有以下特色:
template <class T>
struct select_type
{
static void action()
{
cout << "Generic type" << endl;
}
};
template <>
struct select_type<std::string>
{
static void action()
{
cout << "Specialization for string" << endl;
}
};
template <std::size_t N>
struct select_type<const char[N]>
{
static void action()
{
cout << "Specialization for const char array" << endl;
}
};
当我尝试按如下方式实例化每个专业化时:
select_type<int>::action();
select_type<std::string>::action();
select_type<decltype("abc")>::action();
...我得到以下输出:
Generic type
Specialization for string
Generic type
请注意,即使char
生成类型decltype(abc)
,也不会调用const char[4]
数组的专门化。
我认为也许某种类型的衰变正在发生,所以我添加了const char*
的专业化,但它仍然没有被选中。
那么,为什么表达式为:
select_type<decltype("abc")>::action();
无法调用const char[N]
?
答案 0 :(得分:3)
由于decltype
推断类型的方式,您会看到此行为。字符串文字是左值。来自[expr.prim.general] / p1:
字符串文字是左值;所有其他文字都是prvalues。
decltype()
为lvalues返回左值引用类型。 [dcl.type.simple] / P4
对于表达式
e
,decltype(e)
表示的类型定义如下:(4.1) - 如果
e
是未加密码的id-expression或未加密码的类成员访问(5.2.5),decltype(e)
是e
命名的实体的类型。如果没有这样的实体,或者e
命名一组重载函数, 该计划格式不正确;(4.2) - 否则,如果
e
是xvalue,decltype(e)
是T&&
,其中T
是e
的类型;(4.3) - 否则,如果
e
是左值,decltype(e)
是T&
,其中T
是e
的类型; 强>(4.4) - 否则,
decltype(e)
是e
的类型。
所以你的专业化需要如下:
template <std::size_t N>
struct select_type<const char (&)[N]>