String Literal的模板参数演绎

bwe*_*ber 6 c++ templates string-literals perfect-forwarding c++11

我目前正在考虑如何最好地将通用类型的模板约束到std::sting字符串文字.因此,我使用推断的类型与所需的类型进行比较std::is_same.如果std::string这是立即工作.对于字符串文字,意思是char const数组,它只有在我使用std::decay该类型然后将结果与类型进行比较时才有效char const *.如果我直接将推导出的类型与我认为的类型进行比较,则is_same返回false,如下面的示例代码所示.

template <class TYPE>
void function(TYPE&& parameter)
{
  //this doesn't work as expected
  std::cout << typeid(TYPE).name() << " : " << typeid(char const [5]).name() << std::endl;
  std::cout << std::is_same<char const [5], TYPE>::value << std::endl;
  //this works as expected
  std::cout << typeid(std::decay_t<TYPE>).name() << " : " << typeid(char const *).name() << std::endl;
  std::cout << std::is_same<char const *, std::decay_t<TYPE>>::value << std::endl;
}

int main(int argc, char** argv)
{
  function("name");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成的输出如下:

char const [5] : char const [5]
0
char const * __ptr64 : char const * __ptr64
1
Run Code Online (Sandbox Code Playgroud)

现在,我想知道为什么is_same在第一种情况下返回false,即使类型看起来是相同的.

我能想到的唯一可能的解释是,在函数中,std::is_same类似的转换std::decay应用于类型(例如函数调用).但是,这种转变也会发生在另一种类型中,产生相同的结果,从而导致平等.

Use*_*ess 6

字符串常量没有被价值传递char const [N],而是通过引用作为char const (&)[N].

这适合我:

std::cout << std::is_same<char const (&)[5], TYPE>::value << std::endl;
Run Code Online (Sandbox Code Playgroud)

请注意这里

1)指std::type_info代表示类型类型的对象.如果type是引用类型,则结果引用std::type_info表示引用类型的对象.

您可以轻松验证is_same不会以与type_info检查相同的方式丢弃引用,例如通过检查

std::is_same<int&, int>::value == false
Run Code Online (Sandbox Code Playgroud)

这解释了为什么typeid名称相同,但您的is_same测试仍然失败.