【问题标题】:Pass string literal to template function将字符串文字传递给模板函数
【发布时间】:2021-02-24 23:32:20
【问题描述】:

我尝试为几种类型专门化一个模板函数,其中之一是 const char*。

template<typename T = const char*>
void f(T&&);

template<>
void f<int>(int&& k) { std::cout << "Now in int fcn (" << k << ")!\n"; }

template<>
void f<const char*>(const char* && k) { std::cout << "Now in cc* fcn (" << k << ")!\n"; }

int main() {
  f<int>(5);
  f("HELLO");

  return 0;
}

但是当我执行 f("HELLO") 时,我得到以下错误:

main.cpp:(.text+0x32): undefined reference to `void f<char const (&) [6]>(char const (&) [6])'

如何让它将“HELLO”解释为 const char* 而不是数组?如果我专门研究数组,每个数组大小都需要一个?

此外,通用模板函数捕获 f("HELLO"):

template<typename T>
void f(T&& k) { /* Definition... */ }

它会为我需要的每个数组大小创建一个特化,还是以某种方式将字符串文字转换为“const char*”?

【问题讨论】:

    标签: c++ templates string-literals forwarding-reference


    【解决方案1】:

    字符串文字不是const char*。字符串文字的类型为const char[N],其中N 是字符数加上空终止符。这意味着当您调用函数T 时,会推断为const char[6],它与任何特化都不匹配,因此使用主模板。由于您尚未定义主模板,因此您会收到有关缺少定义的链接器错误。

    您可以通过使用添加函数的重载来处理 char 数组和字符串文字

    template<std::size_t N> void f(const char (&arr)[N]) { stuff; }
    

    是的,它会为每个大小的数组删除一个函数,但这只是一点额外的编译时间,你只需要编写一次主体。


    您还应该阅读Why Not Specialize Function Templates?。在文章中,它详细说明了为什么函数模板特化并不总是像您希望的那样工作,并且它们不参与重载决议。一般来说,你应该重载而不是专门化。

    【讨论】:

    • 谢谢。但这是否意味着我必须为我使用的每个数组大小创建一个专业化?
    • @Skaarjasaurus 取决于你想做什么。如果您希望字符串文字/字符数组调用单个函数,您可以添加 template&lt;std::size_t N&gt; void f(const char (&amp;arr)[N]) { stuff; } 的重载,这将采用任意大小的数组。
    猜你喜欢
    • 1970-01-01
    • 2021-09-02
    • 2013-10-21
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多