【问题标题】:how create c++ Template?如何创建 C++ 模板?
【发布时间】:2014-01-10 03:16:50
【问题描述】:

我目前正在尝试为显示不同值的力量的函数编写模板特化。 我的代码是:

#include <iostream>
using namespace std;
template <class T>
T myfunc(T x)
{
    return x*x;
}
template<>
string myfunc<string>(string ss)
{
    return (ss+ss); 
}
int main()
{
cout<<myfunc("test")<<endl;
return 0;
}

编译失败:

错误 C2784:'std::_String_iterator<_mystr> std::operator +(_String_iterator<_mystr>::difference_type,std::_String_iterator<_mystr>)' : 无法推断出模板参数 来自“std::string”的“std::_String_iterator<_mystr>”

您能帮我找出问题所在吗?

【问题讨论】:

  • "test" 不会被推断为std::string。它的类型为const char[5]

标签: c++ templates


【解决方案1】:

您需要向函数传递一个字符串,而不是一个字符数组。试试myfunc(string("test"))

稍微扩展一下——在调用函数时选择使用哪个模板/模板特化称为模板参数推导。

您希望调用 myfunc,但是测试的类型是 char[5](最后是空字符)。因此,模板参数被“推导出”为 char[5]。

通常,在调用完全专用的函数(不是模板函数)时,char[] 可以隐式转换为字符串(我相信这是不推荐的)。这种隐式转换是因为,正如 user1274223 所指出的,std::string 有一个带有签名 string(const char *) 的构造函数,而这个构造函数是不显式的!当我们想假装 c 字符串 (char*) 可以与 cplusplus 字符串 (std::string) 轻松互换时,这很有帮助,但是在这些类型的情况下它可能会令人困惑。

另一种解决方法是myfunc&lt;string&gt;("test"),因为这里直接传递模板参数,并且可以隐式地强制转换char[]

【讨论】:

  • +1 用于包含 string() 构造。 "test" 被解释为一个 const char 数组,而不是一个字符串,所以这个调用是必要的。
  • 感谢您的清晰解释,但不幸的是它有同样的错误。
  • @user3140486 它对我有用,尝试#include 以防命名空间中缺少“+”运算符
【解决方案2】:

在这种情况下不需要模板特化,你应该重载函数:

std::string myfunc(const std::string &ss)
{
    return (ss+ss); 
}

这样称呼它为myfunct("test") 就可以了。

有关为什么函数模板特化通常没有用的所有详细信息,您可以查看 Herb Sutter 的文章 Why Not Specialize Function Templates?

【讨论】:

  • 是的,但我认为“测试”的目的是让 OP 检查参数是否被推断为他想要的方式
  • 您应该提到 std::string 有一个不显式的 const char * 构造函数,这就是字符串文字将被转换为字符串的原因。
【解决方案3】:

正如其他人已经说过的那样。 另外,我认为你需要

#include <string>

其中声明了字符串和字符串本身的operator+ 您得到的错误是您的编译器尝试匹配所有其他 operator+ 并失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多