首页 > 解决方案 > 如何检查类型'T'是否具有'T(std::initializer_list )'构造函数

问题描述

标签: c++templatesconstructorc++17sfinae

解决方案


有没有办法解决这个问题?

是的。不要解决它。您不应该试图猜测用户想要什么样的初始化。只需这样做:

new (ptr) T(std::forward<Args>(args)...)

如果用户想使用initializer_list构造函数,他们可以传入 an 的实例,initializer_list这样就可以了。

更有趣的情况是聚合,这就是为什么它们可以在 C++20 中用括号初始化(参见P0960)。但这可以通过传入一个具有适当转换运算符的参数来解决。也就是说,如果我想构造一个:

struct X { int i; };

并使用括号使其工作,我可以传入一个类型的参数:

struct X_factory { int i; operator X() const { return X{i}; } };

并且在保证复制省略的情况下,无论如何我们都会得到正确的效果。


无论如何,initializer_list实际上与问题并不严格相关。您可能想要的(我不建议这样做)是:

if constexpr (std::is_constructible_v<T, Args...>) {
    new (ptr) T(std::forward<Args>(args)...);
} else {
    new (ptr) T{std::forward<Args>(args)...};
}

或者可能以相反的顺序为直接列表初始化编写特征。


推荐阅读