滥用逗号运算符

时间:2009-10-12 22:16:35

标签: c++ overloading comma-operator

我正在寻找一种在编译时构建字符串数组的简单方法。对于测试,我将一个名为Strings的类放在一起,该类具有以下成员:

Strings(); 
Strings(const Strings& that);
Strings(const char* s1);
Strings& operator=(const char* s1);
Strings& operator,(const char* s2);

使用这个,我可以成功编译这样的代码:

Strings s;
s="Hello","World!";

s="Hello"部分调用operator=,返回Strings&,然后operator,调用"World!"

我无法工作(在MSVC中,还没有尝试过任何其他编译器)

Strings s="Hello","World!";

我假设Strings s="Hello"会调用复制构造函数,然后一切都与第一个示例相同。但我收到错误:error C2059: syntax error : 'string'

然而,这很好用:

Strings s="Hello"; 

所以我知道复制构造函数至少可以用于一个字符串。有任何想法吗?我真的很想让第二种方法只是为了使代码更清洁。

7 个答案:

答案 0 :(得分:14)

我认为第二个例子中的逗号不是逗号运算符,而是多个变量声明的语法元素。

例如,与你可以写的方式相同:

int a=3, b=4

在我看来,你基本上是写作:

Strings s="Hello", stringliteral

因此编译器期望逗号后面的项是变量的名称,而是看到一个字符串文字并宣布错误。换句话说,构造函数应用于“Hello”,但之后的逗号是不是字符串的逗号运算符。

顺便说一句,构造函数实际上不是一个复制构造函数。它从文字字符串参数创建一个字符串对象......术语复制构造函数通常应用于相同的类型。

答案 1 :(得分:8)

我不推荐这种API。您将继续发现无法按预期工作的情况,因为逗号是具有最低优先级的运算符。例如,这种情况也不起作用:

if ("Hello","world" == otherStrings) { ... }

如果你每次都围绕字符串使用括号,你可能会把事情搞定,如下所示:

Strings s=("Hello","World!");

我上面的例子看起来像这样:

if (("Hello","world") == otherStrings) { ... }

这可能会起作用,但简写语法可能不值得随之附带的棘手语义。

答案 2 :(得分:5)

使用boost::list_of

答案 3 :(得分:1)

对于“工作”的充分宽松定义,可以使这项工作成为可能。这是我几年前回答类似问题时写的一个工作实例。作为一项挑战很有趣,但我不会在实际代码中使用它:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

void f0(std::vector<int> const &v) { 
    std::copy(v.begin(), v.end(), 
        std::ostream_iterator<int>(std::cout, "\t"));
    std::cout << "\n";
}

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

int main() { 
    f0((makeVect(1), 2, 3, 4, 5));
    f0((makeVect(1), 2, 3));
    return 0;
}

答案 4 :(得分:0)

您可以使用字符指针数组

Strings::Strings(const char* input[]);

const char* input[] = {
  "string one",
  "string two",
  0};

Strings s(input);

并在构造函数内部迭代指针,直到你达到null。

答案 5 :(得分:0)

如果你是c ++ 0x,他们就会有新的inializer lists!我希望你能用那些。例如:

std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" };

答案 6 :(得分:0)

如果Strings的唯一工作是存储字符串列表,那么boost::assign可以使用标准容器更好地完成工作,我认为:)

using namespace boost::assign;
vector<string> listOfThings;
listOfThings += "Hello", "World!";