9

我正在寻找一种在编译时构建字符串数组的简单方法。对于测试,我将一个名为的类放在一起,该类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=返回 aStrings&然后调用operator,get 的部分"World!"

我无法开始工作(在 MSVC 中,尚未尝试任何其他编译器)是

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

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

但是,这很好用:

Strings s="Hello"; 

所以我知道复制构造函数至少对一个字符串有效。有任何想法吗?我真的很想让第二种方法工作,只是为了让代码更干净一些。

4

7 回答 7

14

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

例如,您可以编写相同的方式:

int a=3, b=4

在我看来,您实际上是在写:

Strings s="Hello", stringliteral

所以编译器期望逗号后面的项目是变量的名称,而是看到一个字符串文字并宣布错误。也就是说,构造函数作用于“Hello”,但是后面的逗号不是Strings的逗号操作符。

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

于 2009-10-12T22:29:59.577 回答
8

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

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

如果您每次都在字符串集周围使用括号,则可以使事情正常进行,如下所示:

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

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

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

这可能会起作用,但速记语法可能不值得随之而来的棘手语义。

于 2009-10-12T22:34:56.353 回答
5

使用boost::list_of.

于 2009-10-12T22:32:07.533 回答
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;
}
于 2009-10-12T23:24:16.770 回答
0

您可以使用字符指针数组

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

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

Strings s(input);

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

于 2009-10-12T22:37:23.863 回答
0

如果你是 c++0x,他们有新的初始化列表!我希望你能用这些。例如:

std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" };
于 2009-10-12T22:39:08.200 回答
0

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

using namespace boost::assign;
vector<string> listOfThings;
listOfThings += "Hello", "World!";
于 2009-10-12T22:46:35.963 回答