2

フォーマット付きの構成ファイルを次のように定義されkey: valueたものに読み取る構成ファイルパーサーを作成していますstd::map<string, ConfigVariantConfigVarianttypedef boost::variant<double, long int, std::string> ConfigVariant;

私の構成クラスの重要な部分は次のとおりです。

typedef boost::variant<double, long int, std::string> ConfigVariant;

class Config {
private:
  std::map<std::string, ConfigVariant> config_values;

  // This struct is important
  struct Proxy {
  public:
    template<typename T> T as() { return boost::get<T>(data); }
    template<typename T> operator T() { return as<T>(); }

  private:
    ConfigVariant data;

    Proxy(ConfigVariant data) { this->data = data; }
    Proxy(const Proxy &other);
    Proxy & operator=(const Proxy &other);
    friend class Config;
  };

public:
  Config(std::string config_file_name);
  Proxy operator[] (const std::string &key); // Important
};

関連する唯一の実装は、次のoperator[]ようなものです。

Config::Proxy Config::operator[] (const string &key) {
  return Proxy(config_values[key]);
}

このコードにより、次のようなことができます。

// config_file
double_key: 4.2

// driver.cpp
int main() {
  Config config("path/to/config_file");

  double d = config["double_key"] // Look ma, no cast
  d += 1

  cout << d << endl; // Prints 5.2

  return 0;
}

この動作には満足していますが、ご覧のとおり、 からの参照を返すことができませんoperator[]。参照を返さないため、 を介して代入を実行できませんoperator[]。ハッシュから構成値をロードした後に構成値を変更したいので、これはやや問題です。config["key"]また、構文を維持したいと思います。何か案は?

編集:

Proxy を store に変更してからConfigVariant *、オーバーロードを試みoperator=ました。これがまさに私が試したことです:

Proxy & operator=(ConfigVariant &other) { *data = other; return *this; }

これにより、次のエラーが発生しました。

app/driver.cpp: In function ‘int main()’:
app/driver.cpp:11: error: no match for ‘operator=’ in ‘Config::operator[](const std::string&)(((const std::string&)(& std::basic_string<char, std::char_traits<char>, std::allocator<char> >(((const char*)"key3"), ((const std::allocator<char>&)((const std::allocator<char>*)(& std::allocator<char>()))))))) = 5.20000000000000017763568394002504646778106689453125e+0’
app/../config/config.hpp:37: note: candidates are: Config::Proxy& Config::Proxy::operator=(const Config::Proxy&)
app/../config/config.hpp:44: note:                 Config::Proxy& Config::Proxy::operator=(ConfigVariant&)

それから私は試しました:

ConfigVariant & operator=(ConfigVariant &other) { *data = other; return *data; }

これにより、ほぼ同じエラーが発生しました。

app/driver.cpp: In function ‘int main()’:
app/driver.cpp:11: error: no match for ‘operator=’ in ‘Config::operator[](const std::string&)(((const std::string&)(& std::basic_string<char, std::char_traits<char>, std::allocator<char> >(((const char*)"key3"), ((const std::allocator<char>&)((const std::allocator<char>*)(& std::allocator<char>()))))))) = 5.20000000000000017763568394002504646778106689453125e+0’
app/../config/config.hpp:37: note: candidates are: Config::Proxy& Config::Proxy::operator=(const Config::Proxy&)
app/../config/config.hpp:44: note:                 ConfigVariant& Config::Proxy::operator=(ConfigVariant&)
4

2 に答える 2

2

ProxyConfigVariant現在、マップからのコピーを保存しています。代わりに、マップ内の元のオブジェクトへの参照またはポインターを格納します。Proxy::operator=次に、その値に割り当てるように実装できます。

于 2013-07-27T04:30:18.150 に答える