【问题标题】:Template argument deduction for 'char*''char*' 的模板参数推导
【发布时间】:2016-06-05 23:26:11
【问题描述】:

我有以下功能(仅用于重现问题):

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

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

func<char*>("literal");

但是,我最终得到以下警告:

警告:ISO C++11 不允许从字符串文字转换为 'char *' [-Wc++11-compat-deprecated-writable-strings]

我特别需要使用 char* 作为我的密钥类型,并且我期望 TADparam type 整体视为 const char*,因为我没有将其作为参考。

clangg++ 编译器都带有警告。

param type 这里是如何推导出来的?

提前致谢。

【问题讨论】:

  • cptr 最终成为 const 指向字符的指针 (char *const),而不是指向 const char 的指针。
  • @melpomene 怎么会这样?
  • 你的声明说cptr必须是const,你用char *实例化KeyT。所以cptr 是一个常量 KeyT(其中 KeyT = 指向字符的指针)。

标签: c++ templates c++11


【解决方案1】:

我期待 TAD 将参数类型视为 const char* ...
这里如何推导出参数类型?

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

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

"literal" 是类型为const char[8] 的sring 字面量,它可能会衰减为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);

【讨论】:

  • Why you need the template parameter type to be char*? To modify it inside the function?。不,这只是我展示的一个例子。我实际上使用char* 作为一些自制容器的键类型,它将提供的文字复制到容器数据结构中。我想在不使用 remove_const / decay 特征的情况下尝试一下。
  • @Arunmu 如果您不修改它,使用const char* 就可以了(将模板参数指定为const char* 或根本不指定)。如果没有,你必须做一些更像我的回答所示的事情。
  • 是的,看起来就是这样。我可能需要重新考虑我的界面。
【解决方案2】:

这里没有推演:你已经明确声明模板参数是char*

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

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多