c++ - 如何在不显式调用显式构造函数的情况下初始化映射?

标签 c++ stdmap initializer-list

我正在尝试使用初始化列表初始化 std::map(在生产中,这是一个类的成员初始化器,但我的最小失败示例如下)。给定

#include <map>

struct Cfg {};

struct Alg
{
    explicit Alg(Cfg const&) {}
};

using MyMap = std::map<int, Alg>;

int main()
{

    Cfg cfg;

    MyMap m = {
        {1, {cfg}},      // error #1
        {2, cfg},        // error #2
        {3, Alg(cfg)},   // works fine
    };

  return 0;
}

编译时,错误 #1 是:

foo.cc: In function ‘int main()’:
foo.cc:22:5: error: converting to ‘const Alg’ from initializer list would use 
explicit constructor ‘Alg::Alg(const Cfg&)’
     };
     ^

这很简单。将 Cfg 传递给初始化器需要转换,显式构造函数禁止它。

错误 #2 是

foo.cc: In function ‘int main()’:
foo.cc:22:5: error: converting to ‘std::pair<const int, Alg>’ from initializer list would use explicit constructor ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U1 = int; _U2 = Cfg&; typename std::enable_if<(std::_PCC<true, _T1, _T2>::_MoveConstructiblePair<_U1, _U2>() && (! std::_PCC<true, _T1, _T2>::_ImplicitlyMoveConvertiblePair<_U1, _U2>())), bool>::type <anonymous> = 0; _T1 = const int; _T2 = Alg]’
     };
     ^

这有点令人困惑。我认为错误是关于隐式调用显式 std::pair 构造函数;阅读 std::pair 的文档,我迷失了构造函数在什么时候是显式的。

第三种情况是显式构造。出于可维护性的原因,我宁愿不这样做。

我好像读过很多初始化列表反直觉的问题可以通过添加更多大括号(粗略简化)来解决,但我承认我在这一点上迷路了。

如果我删除 Alg 构造函数的 explicit 限定条件,所有三种情况都会编译。但是,我不确定仅仅为了简化初始化列表而提供隐式转换是否有意义。

有没有一种方法可以在不显式构造 Alg 成员的情况下初始化我的 map 元素?使用 g++ 7.3

最佳答案

据我所知,没有办法绕过指定 Alg 类型。无论如何,这就是 explicit 构造函数的意图。只是为了[我不知道在这里说什么],您仍然可以调用 std::pair 的就地构造函数,如下所示。

MyMap m{{std::piecewise_construct, std::forward_as_tuple(1), std::tie(cfg)}};

这样,您就不必键入 Alg,它会回答您的问题。此外,仅当您讨厌自己和同事时才执行上述操作。

注意:std::pair 的就地构造函数实际上存在以允许不可复制、不可移动的类型。

关于c++ - 如何在不显式调用显式构造函数的情况下初始化映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55958807/

相关文章:

c++ - 跨多个对象使用 map

c++ - 为什么在 std::vector 的初始化列表中调用复制构造函数?

c++ - 为 C++ 配置 google glog 和 gflags

c++ - "ContainsElement"和 "DoesContainElement"之间哪个更常规的函数名称?

c++ - Qt 还原我在 ui 文件中的更改

c++ - 错误 : no matching function for call to default copy constructor?

c++ - 在 C++ 中返回映射的函数

c++ - 如何为 std::array 的列表初始化构造函数编写包装器?

c++ - 使用初始值设定项列表从多个字符数组构造 std::string

c++ - 在 C++ 中更改 QML font.pointSize