'char *'的模板参数推导

时间:2016-06-05 12:43:25

标签: c++ templates c++11

我有以下功能(仅用于复制问题):

template <typename KeyT>
void func(const KeyT cptr) {
  std::cout << typeid(KeyT).name() << std::endl;
}

我想用字符串文字调用它,如下所示:

func<char*>("literal");

但是,我最终得到了警告:

warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wc++11-compat-deprecated-writable-strings]

我特别需要使用char*作为我的密钥类型,我希望TADparam type视为const char*,因为我没有接受它通过引用。

警告来自clangg++编译器。

param type如何在此推断?

提前致谢。

2 个答案:

答案 0 :(得分:12)

  

我期待TAD将param类型视为const char * ...
  如何在这里推断出param类型?

template <typename KeyT>
void func(const KeyT cptr)

注意constKeyT本身的限定符,这意味着如果KeyT是一个指针,那么cptr将是一个const指针,而不是指向const的指针

"literal"使用类型为const char[8]的字面值,可能会衰减到const char*。然后,KeyT可能会被推断为const char*,然后cptr的类型将为const char* const

您将模板参数类型指定为char*,然后将cptr指定为char* const。但是从C ++ 11开始,不允许隐式地将字符串文字转换为char*,因为文字是const

为什么模板参数类型需要为char*?要在函数内修改它吗?请注意,修改字符串文字将导致UB。您可以将char数组传递给它,例如:

char my_chararray[] = "literal";
func<char*>(my_chararray); // or just func(my_chararray);

答案 1 :(得分:8)

此处没有演绎:您已明确声明模板参数为char*

您缺少的是参数替换不是文本搜索和替换:它实际上遵循类型系统的逻辑规则。 const KeyT cptr声明const类型的KeyT实例 - 当KeyTchar*时,参数声明变为char *const cptr