1

假设你有一个命名空间

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.

4

3 回答 3

4

类型s1s2携带有关它们被声明的命名空间的信息。

不过,您可以很容易地包装自定义类型。

namespace approvedParams
{
   struct keytype { std::string val; };
   keytype s1 = { "my_string_input_1" };
   keytype s2 = { "my_string_input_2" };
}

void approvedParams( approvedParams::keytype );
于 2013-04-25T22:04:23.513 回答
2

创建一个enum已批准的参数值

enum approvedParams {
    val1 = 0,
    val2, ...
};

只需使用这些索引创建一个包含字符串的数组

std::string[] approvedParamValues = { "my_string_input_1", ... };
于 2013-04-25T22:04:39.657 回答
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对象,但他只有一组有限的(不可变的)实例可供选择,他将无法创建全新的实例。

于 2013-04-25T23:08:24.237 回答