假设您有一个名称空间
approvedParams {
std::string s1 = "my_string_input_1";
std::string s2 = "my_string_input_2";
}
在approvedParams
范围之外,存在一个函数myfun(std::string parm1)
是否可以将myfun
签名限制为仅接受来自std::string
命名空间的approvedParams
类型的字段?
那是:
myfun("my_string_input_1")
无法编译。
myfun(approvedParams::s1)
将编译。
我正在考虑使用enum
进行实施。但是,当我解析键值配置文件时,我最终希望使用approvedParams::s1
和s2
。 enum
必须是完整的类型。我对使用map<int,std::string>
添加另一个不必要的图层以将枚举整数与std::string
连接起来不感兴趣。
答案 0 :(得分:4)
s1
和s2
的类型不包含有关它们声明的命名空间的信息。
您可以更轻松地换行自定义类型。
namespace approvedParams
{
struct keytype { std::string val; };
keytype s1 = { "my_string_input_1" };
keytype s2 = { "my_string_input_2" };
}
void approvedParams( approvedParams::keytype );
答案 1 :(得分:2)
创建enum
已批准的参数值
enum approvedParams {
val1 = 0,
val2, ...
};
只需使用这些索引创建一个包含字符串的数组
std::string[] approvedParamValues = { "my_string_input_1", ... };
答案 2 :(得分:1)
这是我的看法,重复使用@ DrewDormann关于包装类型的想法,但实际上强制使用它。
这个想法基本上是命名构造函数习惯用法的变体,但只有静态变量而不是完全成熟的工厂函数(这种模式是否有名称?)。
// Declaration in .h
class ApprovedParam
{
public:
static const ApprovedParam foo;
static const ApprovedParam bar;
const std::string& value() const { return m_value; }
private:
std::string m_value;
ApprovedParam(const char* value) : m_value(value) {}
ApprovedParam(std::string&& value) : m_value(std::move(value)) {}
ApprovedParam(const std::string& value) : m_value(value) {}
// IMPORTANT: the user must not be able to default construct an ApprovedParam
ApprovedParam() = delete;
};
// Definitions in .cpp
const ApprovedParam ApprovedParam::foo = "foo";
const ApprovedParam ApprovedParam::bar = "bar";
现在用户可以复制/移动/分配ApprovedParam
个对象,但他只有一组有限的(不可变的)实例可供选择,而且他将无法创建全新的实例。