c++ - 如何防止 std::string 使用 initializer_list 构造函数?

标签 c++ c++11 initializer-list list-initialization

对于使用与其他基本类型相同的初始化的 std::string 的情况,我希望以下代码输出“test”而不是“X”。 std::string 现在调用带有 initializer_list 的构造函数,因此 get 的模板特化为 char 被调用.

#include <sstream>
#include <string>
#include <iostream>

// Imagine this part as some kind of cool parser.
// I've thrown out everything for a simpler demonstration.
template<typename T> T get() {}
template<> int get(){ return 5; }
template<> double get(){ return .5; }
template<> char get(){ return 'X'; }
template<> std::string get(){ return "test"; }

struct Config {
    struct proxy {
        // use cool parser to actually read values
        template<typename T> operator T(){ return get<T>(); }
    };

    proxy operator[](const std::string &what){ return proxy{}; }
};

int main()
{
    auto conf = Config{};

    auto nbr = int{ conf["int"] };
    auto dbl = double{ conf["dbl"] };
    auto str = std::string{ conf["str"] };

    std::cout << nbr << std::endl; // 5
    std::cout << dbl << std::endl; // 0.5
    std::cout << str << std::endl; // 'X'
}

有没有一种很好的方法可以在不破坏变量初始化的一致外观的情况下做到这一点?

最佳答案

std::string有一个接受 initializer_list<char> 的构造函数争论;当您将列表初始化与非空的花括号初始化列表一起使用时,将始终首先考虑该构造函数,这就是为什么 char特化get()正在匹配。

如果您在所有初始化中使用圆括号而不是大括号,则 initializer_list构造函数将不再是 std::string 中唯一考虑的构造函数案例。

auto nbr = int( conf["int"] );
auto dbl = double( conf["dbl"] );
auto str = std::string( conf["str"] );

但是,仅此更改是行不通的,因为您有一个可以产生任何类型的隐式用户定义转换模板。上面的代码,在 std::string 中案例,结果匹配所有 std::string可以用单个参数调用的构造函数。要解决此问题,请使用转换运算符 explicit .

struct proxy {
    // use cool parser to actually read values
    template<typename T>
    explicit operator T(){ return get<T>(); }
};

现在,只有显式转换为 std::string是可行的,并且代码按照您希望的方式工作。

Live demo

关于c++ - 如何防止 std::string 使用 initializer_list 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25021300/

相关文章:

c++ - 初始化列表中的序列点警告

C++11 初始化列表失败 - 但仅在长度为 2 的列表上

qt - 初始化 QWidgets 的合适位置是什么?

vector 的 C++ 引用

c++ - SOMTEMPLATE_VR_API 是什么?

c++ - 如何转换现有回调接口(interface)以使用 boost 信号和槽

c++ - 如何使用静态 C++ 库扩展 Lua?

c++ - 如何使用 std::map 在 C++ 中检索 std::vector<int>?

c++ - 以不同方式分派(dispatch)右值和左值并使用 sfinae 禁用一个选项

c++ - 为什么 one-definition-rule-use (odr-use) 取决于上下文?