我有一个struct / class,它有许多属性,其中一个是principal。在构造此类的实例时,必须在参数中给出principal属性,但是可以提供或不提供任何其他属性。如果未提供属性作为参数,则应从主要属性计算。
我不知道如何在不编写指数数量的构造函数的情况下编写这样的类;或者在每个构造函数之后使用setter,它只有一个参数对应于principal属性。
我在这里给出一个最适合我的例子。但这当然没有编译:
#include <cstdlib>
#include <iostream>
using namespace std;
struct StringInfo
{
string str;
int importance;
StringInfo(string strP, int importanceP = strP.length()):
str(strP), importance(importanceP){}
};
int main(int argc, char** argv) {
string test = "test";
StringInfo info(test);
cout << info.importance << endl;
}
你有更好的(非指数)解决方案吗? 提前谢谢。
答案 0 :(得分:2)
您几乎想要一种类似于Python的可选参数的行为,例如:
callFunction(param1=2, param3="hello")
如果您有一个类型已擦除键值对的地图,您可以在C ++中执行此操作:
map<string, ErasedType> _m;
地图的键是一个包含成员描述的字符串(由您决定选择此项)。
让我们暂时离开ErasedType
。如果你有这样的成员,你可以写:
class MyClass
{
map<string, ErasedType> _m;
public:
MyClass(map<string, ErasedType> const& args) : _m(args) {}
};
这样您只需指定所需的键并为其指定特定值。构造这种构造函数的输入的一个例子是
map<string, ErasedType> args = { {"arg1", 1}, {"arg1", 1.2} };
然后访问特定值将采用如下的成员函数:
ErasedType get(string const& name) { return _m[name]; }
现在ErasedType
。最典型的方法是将它作为您保留的所有可能类型的联合:
union ErasedType { // this would be a variant type
int n;
double d;
char c;
};
第二个想法是让地图值成为boost::any
容器的一个实例。第三个想法(更旧的学校)是使用void*
#include <map>
#include <string>
#include <iostream>
#include <boost/any.hpp>
using namespace std;
using boost::any_cast;
class OptionalMembers
{
map<string, boost::any> _m;
public:
OptionalMembers(map<string, boost::any> const& args) : _m(args)
{
// Here you would initialize only those members
// not specified in args with your default values
if (args.end() == args.find("argName")) {
// initialize it yourself
}
// same for the other members
}
template<typename T>
T get(string const& memberName) {
return any_cast<T>(_m[memberName]);
}
};
int main()
{
// say I want my OptionalMembers class to contain
// int argInt
// string argString
// and then more members that won't be given
// as arguments to the constuctor
std::string text("Hello!");
OptionalMembers object({ { "argInt", 1 }, { "argString", text } });
cout << object.get<int>("argInt") << endl;
cout << object.get<string>("argString") << endl;
return 0;
}
在前面的示例中,您可以自由地拥有尽可能多的&#34;成员&#34;如你所愿,并在构造函数中随意指定每一个
答案 1 :(得分:1)
实际上,您最终会得到像
这样的代码Example object = MakeExample().Parameter1().Parameter2(12345).Parameter3(false);