C++ 滥用逗号运算符

C++ 滥用逗号运算符,c++,overloading,comma-operator,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"

我正在寻找一种在编译时构建字符串数组的简单方法。为了进行测试,我创建了一个名为
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!";
Strings s=("Hello","World!");
if (("Hello","world") == otherStrings) { ... }
s=“Hello”
部分调用
操作符=
,该操作符返回一个
字符串&
,然后调用
操作符
“World!”

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

我在这里假设
Strings=“Hello”
将调用复制构造函数,然后所有操作都将与第一个示例相同。但是我得到了错误:
error C2059:syntax error:'string'

但是,这样做很好:

Strings s="Hello"; 

所以我知道复制构造函数至少对一个字符串起作用。有什么想法吗?我真的希望第二个方法能够使代码更简洁。

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

e、 例如,你可以用同样的方式写:

int a=3, b=4
在我看来,你基本上是在写:

Strings s="Hello", stringliteral
因此,编译器希望逗号后的项是变量的名称,相反,它看到一个字符串文本并宣布一个错误。换句话说,构造函数应用于“Hello”,但后面的逗号不是字符串的逗号运算符


顺便说一下,构造函数并不是真正的复制构造函数。它从文本字符串参数创建字符串对象。。。术语复制构造函数通常应用于同一类型

使用。

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

if ("Hello","world" == otherStrings) { ... }
如果每次都在字符串集周围使用括号,则可能会使事情正常进行,如下所示:

Strings s;
s="Hello","World!";
Strings s=("Hello","World!");
if (("Hello","world") == otherStrings) { ... }
我上面的例子是这样的:

Strings s;
s="Hello","World!";
Strings s=("Hello","World!");
if (("Hello","world") == otherStrings) { ... }

这可能是可行的,但速记语法可能不值得它附带的复杂语义。

您可以使用字符指针数组

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

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

Strings s(input);

在构造函数内部,遍历指针,直到找到空值。

如果使用c++0x,则它们有新的指针!我希望你能用这些。例如:

std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" };
std::vector v={“xyzy”、“plugh”、“abracadabra”};
向量v{“xyzy”,“plugh”,“abracadabra”};

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

使用名称空间boost::assign;
矢量物品清单;
物品清单+=“你好”,“世界!”;

这是可能的,因为“工作”的定义非常松散。这是我几年前为回答类似问题而编写的一个工作示例。这是一个有趣的挑战,但我不会在真正的代码中使用它:

#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;
}
#包括
#包括
#包括
#包括
void f0(std::vector const&v){
复制(v.begin(),v.end(),
std::ostream_迭代器(std::cout,“\t”);

std::这能起作用吗?我预见的问题是你不能重载
操作符,
对于
常量字符*
,所以
(“你好”,“世界”)
“世界”
一样。我假设你可以重载操作符,(常量字符*,常量字符*)有没有一个原因,为什么我不能这么做?老实说,我没有做太多的C++编程。哇,我听到过很多关于逗号重载的笑话。我从来没有指望有人会真正去做它。在你自己的棺材中钉钉子。当它开始出错时,你将如何调试它?“卡尔:你现在的意思是?”:对于一个脚本化的界面,我强烈建议不要使用C++。你最好选择像Lua()这样的东西。这是一个C++脚本,它被设计成可脚本化和嵌入的。沿着使C++更友好的路径通向深奥和黑暗的地方。冒着繁琐迂腐的危险,<代码>字符串S =“hello”;相当于<代码>字符串s=字符串(“hello”)。
。它要求copy-ctor可以调用,甚至可以调用它,从临时对象构造
s
。但是使用
const-char*
构造函数直接初始化
s
,而不使用任何临时对象来替换它的优化是允许的和常见的。Duh,真不敢相信我没有看到这个。或者模板构造函数:
template Strings(const char*(&input)[N]){for(inti=0;i
。然后不需要空终止符:您可以执行
const char*input[]={“this”,“that”};字符串s(input);
。不确定它是否真的值得,但如果你喜欢这类东西,它会很有趣。哦,或者当然,构造函数模板可以调用另一个类似于
vector::insert(迭代器、InputIterator、InputIterator)
的函数,以避免在不同的位置以不同的长度调用它时生成重复的代码。