由于您显然只需要可转换为字符串的字符串和字符数组,因此您只需要可变数量的字符串参数。
首先想到的是std::vector。
std::string to_chat_message(std::vector<std::string> v) {
//do something with the strings in v...
}
在 C++11 中
这可以很容易地与初始化列表一起完成:
//...
string str{"meh"};
write(to_chat_message({"hey", " ", "hey", str, "what?"}));
为了方便,去掉花括号,你可以写一个可变参数模板:
template <class... Args>
std::string to_chat_message(Args&&... args) {
return to_chat_message({ std::forward<Args>(args)... });
}
// and now...
write(to_chat_message("hey", " ", "hey", str, "what?"));
在 C++03 中
你既没有可变参数模板也没有初始化列表。但是你有 boost.assign:
#include <boost/assign/list_of.hpp>
using boost::assign::list_of;
write(to_chat_message(list_of<std::string>("hey")(" ")("hey")(str)("what?")));
这是一个更冗长的机器人,所以你可以推出一个便利功能,但这必须依赖于 list_of 的提升细节实现:
boost::assign::assign_detail::generic_list<std::string> sl(std::string const& str)
{ return boost::assign::list_of(str); }
write(to_chat_message(sl("hey")(" ")("hey")(str)("what?")));
或者你推出你自己的实现,只是为了这个目的:
struct ToChatMessage {
std::vector<std::string> strings;
ToChatMessage(std::string const& str) {strings.push_back(str);}
operator std::string() const { return to_chat_message(strings); }
ToChatMessage& operator()(std::string const& str) {
strings.push_back(str);
return *this;
}
};
write(ToChatMessage("hey")(" ")("hey")(str)("what?"));
这主要是 list_of 所做的:使用最左边的调用(构造函数)创建一个包含字符串向量的对象并将第一个参数推入该向量。其他调用 (operator()) 将更多值推入向量中。您可以链接 thise 调用,因为 operator() 返回对该对象的引用。最后,由于write() 只接受字符串而不接受ToChatMessage 类型的对象,因此该对象通过调用operator string() 转换为字符串,从而将字符串向量传递给to_chat_message。
除了重载operator(),您当然可以使用其他运算符,具体取决于您希望调用的样子,例如operator<<:
write(ToChatMessage() << "hey" << " " << "hey" << str << "what?" );
当然,有可能通过接受一个到 N 个参数来重载 to_chat_message,但这意味着您要么必须手动重复几乎相同的内容 N 次,否则您将不得不使用像 Boost 这样的预处理器魔法.预处理器并创建一个不可读、难以维护和不可调试的混乱来定义所有这些重载。