【问题标题】:Variadic function dosen't accept string objects可变参数函数不接受字符串对象
【发布时间】:2013-02-24 21:16:27
【问题描述】:

阅读可变参数函数时,我发现了一个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;
}

错误:

'const char [7]' 和 'const char [6]' 类型的无效操作数 二进制'运算符+'

我希望它连接 Hello!World 并打印出 Hello!World。 有什么问题?

【问题讨论】:

  • const char* 没有重载operator+,就像它在错误中所说的那样。如果你问我就很清楚了。

标签: c++ templates c++11


【解决方案1】:

字符串文字不是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 + 对象存在两个对应的 operator + 重载):

auto x = sum(std::string("Hello!") + "World");

或:

auto x = sum("Hello!" + std::string("World"));

当然,您也可以包装两个参数,但这是不必要的。

【讨论】:

  • auto x = sum(string("Hello!"), string("World")); !
  • @MM.:是的。那是因为您将文字包装在 string 对象中
  • 在问更糟糕的问题之前我还是先睡吧!
【解决方案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;
}

Live example.

【讨论】:

    猜你喜欢
    • 2013-08-07
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2017-05-23
    • 2016-09-03
    • 1970-01-01
    • 2011-04-04
    相关资源
    最近更新 更多