阅读变量函数,我发现了一个sum
函数,它接受任意数量的任何数字类型并计算它们的总和。
具有此函数的模板化特性,我希望它接受string
个对象,因为为字符串定义了运算符+
。
#include <iostream>
#include <string>
#include <type_traits>
#include <utility>
using namespace std;
template <typename T> T sum(T && x)
{
return std::forward<T>(x);
}
template <typename T, typename ...Args>
typename std::common_type<T, Args...>::type sum(T && x, Args &&... args)
{
return std::forward<T>(x) + sum(std::forward<Args>(args)...);
}
int main()
{
auto y = sum(1, 2, 4.5); // OK
cout << y << endl;
auto x = sum("Hello!", "World"); // Makes error
cout << x << endl;
return 0;
}
错误:
类型的无效操作数&#39; const char [7]&#39;和&#39; const char [6]&#39;至 二元&#39;运算符+&#39;
我希望它连接Hello!
和World
并打印出Hello!World
。
有什么问题?
答案 0 :(得分:2)
字符串文字不是std::string
个对象。没有为字符数组定义operator +
。
正如您的编译器告诉您的那样,"Hello!"
的类型为const char[7]
,而"World"
的类型为const char[6]
。尝试声明这些类型的两个变量并取其总和:
int main()
{
char const a[7] = "Hello!";
char const b[6] = "World";
(a + b);
}
编译器会向您显示类似的错误:
error: invalid operands of types 'const char [7]' and
'const char [6]' to binary 'operator+'
要使代码正常工作,请将两个字符串文字中的至少一个包装到std::string
对象中(operator +
个对象存在两个相应的std::string
重载:
auto x = sum(std::string("Hello!") + "World");
或:
auto x = sum("Hello!" + std::string("World"));
当然,您也可以包装两个参数,但这是不必要的。
答案 1 :(得分:2)
底层问题不是使用可变参数模板,而是符合您的期望 - 字符串文字(如"hello"
)不属于std::string
类型。它们的类型为char const[N]
,其中N
是字符数+ 1.如果您实际构造了一个字符串(或者甚至只是从第一个字符串构建),它按预期工作:
// snip
int main()
{
auto y = sum(1, 2, 4.5); // OK
cout << y << endl;
auto x = sum(std::string("Hello!"), "World"); // OK
cout << x << endl;
return 0;
}