因此,这里有些C ++开发人员感到困惑。
我有一个正在使用的自定义String
类,它应该教我如何熟悉这些类和其他一些C ++功能,并且该类具有一个value
属性,用于保持跟踪其原始值(即std::string
)。
但这是一个问题,我定义了多种方法来创建此类的对象。我完全理解其中2个:
String stringA = "Hello, World!";
String stringB = String("Hello, World!");
但是最后一个有点棘手,因为它应该能够(从理论上)使用无限的参数集。
String stringC = String("Hello,", ' ', "World!");
但是,当我访问这些字符串的原始值时,最后一个似乎出错了,并且(尽我最大的调试努力)返回了任何东西,乱码的文本或只是给定的部分参数。
stringA.valueOf(); // -> Hello, World!
stringB.valueOf(); // -> Hello, World!
stringC.valueOf(); // -> Hello,
现在,这一直是我一直在努力克服的挑战,尤其是当JavaScript开发人员涉足C ++时。我知道这两种语言在根本上是不同的,但是我认为从逻辑上讲前者应该有一些功能可以在后者上应用(例如可变参数)。
对于任何可以帮助您并向我解释我所缺少的内容(或为什么我的代码很烂的人)的人,您都是绝对的冠军。很高兴。
#include <iostream>
/* Let's assume there's a `stringify` function that converts any value to `std::string` */
class String {
private:
std::string value;
public:
template <typename data>
String(data arg) { this -> value += arg; }
template <typename data, typename... argumentsData>
String(data arg, argumentsData... args) {
this -> value += arg;
String(args...);
}
template <typename data>
String operator =(data arg) { return String(this -> value = arg); }
std::string valueOf() const { return this -> value; }
};
int main() {
String stringA = "Hello, World!";
String stringB = String("Hello, World!");
String stringC = String("Hello,", ' ', "World!");
std::cout << "String A: " << stringA.valueOf() << std::endl;
std::cout << "String B: " << stringB.valueOf() << std::endl;
std::cout << "String C: " << stringC.valueOf() << std::endl;
return 0;
}
答案 0 :(得分:5)
在您的构造函数中
template <typename data, typename... argumentsData>
String(data arg, argumentsData... args) {
this -> value += arg;
String(args...);
}
此行:String(args...);
创建并丢弃一个临时 String
,这不会影响原始对象的状态。
我建议您使用折叠表达式,而不是尝试通过递归来解决此问题:
template <typename ...P>
String(const P &... params) // Passing by const reference is purely an optimization.
{
((value += params) , ...);
}