当前位置: 首页 > 知识库问答 >
问题:

可选地支持模板的initializer_list构造,或者包装容器

乔丁雨
2023-03-14

如果我有一个包装标准容器的模板,我似乎可以很容易地委托initializer_list构造函数:

template<typename T>
struct holder {
    T t_;

    holder() :
        t_() {}

    holder(std::initializer_list<typename T::value_type> values)
        : t_(values) {}

};

例如,这适用于std::向量。

int main(int argc, char* argv[]) {

    holder<std::vector<int>> y{1,2,3};
    return EXIT_SUCCESS;
}

但是很明显,它不适用于T作为“int”,或者任何其他没有嵌套value_typetypedef的类型。所以,我想使用某种enable_if或类似的技巧来使initializer_list构造函数不被发出,除非T都定义了嵌套value_typetypedef,并且可以从std::initializer_list构造。

我尝试了以下方法,但它仍然不起作用,因为编译器(在我的例子中为clang 3.1)在T为int时仍然跳过无效的T::value_type:

holder(typename std::enable_if<std::is_constructible<T, std::initializer_list<typename T::value_type>>::value, std::initializer_list<typename T::value_type>>::type values)
    : t_(values) {}

关于如何表达概念的任何想法“在T上给这个模板一个Tvalue_type上的初始化列表构造函数,当且仅当T有一个value_typetypedef并且可以从T的initializer_list构造::value_type”。

共有1个答案

班高明
2023-03-14

SFINAE仅适用于模板参数替换(因此SFINAE中的S)。以下工作:

template<typename T>
struct holder {
    T t_;

    holder() :
        t_() {}

    template<typename U = T>
    holder(typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, 
    std::initializer_list<typename U::value_type>>::type values)
    : t_(values) {}

};

如果您没有使用模板函数,那么整个类将被实例化为int类型(在您的示例中),从而导致编译器错误。

请注意,如果您使用额外的模板参数,您可以使函数签名更好:

template<typename U = T, class = typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, bool>::type>
    holder(std::initializer_list<typename U::value_type> values)
    : t_(values) {}
 类似资料:
  • 我用模板复制构造函数写了一段代码,以便更好地理解这个概念,因为我是新手,但是下面的代码无法编译 在Visual Studio中编译上述代码时出现以下错误:- 错误:- 严重性代码描述项目文件行抑制状态错误C2558类“网格”:没有可用的复制构造函数或复制构造函数被声明为“显式” 我试图用E替换参数的模板,但它显示了更多的错误(奇怪的错误) 错误: 严重性代码描述项目文件行抑制状态错误LNK2019

  • 组件模型 构造支持器是实现了 IContributeComponentModelConstruction 接口的对象。顾名思义,在组件模型创建之后,它们其将正确的构造到最终状态。 :warning: 不要在支持器的外面修改 ComponentModel: 不鼓励在构造支持器的外面修改组建模型。在 组建模型 被它的构造支持器处理完成之后,它应该是只读的。 在以后的任何时候修改都可能导致并发(conc

  • 在windows下安装一个软件很轻松,只要双击.exe的文件,安装提示连续“下一步”即可,然而linux系统下安装一个软件似乎并不那么轻松了,因为我们不是在图形界面下。所以你要学会如何在linux下安装一个软件。 在前面的内容中多次提到的yum,这个yum是Redhat所特有的安装RPM程序包的工具,使用起来相当方便。因为使用RPM安装某一个程序包有可能会因为该程序包依赖另一个程序包而无法安装。而

  • 谁能解释一下我如何用presto编写这个查询?我发现另一篇文章似乎暗示它的工作正确,所以我有点困惑。

  • 问题内容: 根据这些评论,JSONKit不支持ARC,甚至在ARC环境中都不使用fobjc-no- arc设置运行:https : //github.com/johnezang/JSONKit/issues/37 问题答案: 您仍然可以在ARC应用程序中使用JSONKit。 我自己用的。 在XCode 5中选择项目根目录,在“ 选择应用程序”下,然后选择“ 选项卡”。在JSONKit.m 下,双击

  • 问题内容: 有没有一种方法可以为使用模板的Cython包装的C ++类创建Python包装器?(即完全按照此处显示的内容进行操作,但要使用模板:http : //docs.cython.org/src/userguide/wrapping_CPlusPlus.html#create-cython- wrapper- class)。 我知道融合类型的变通方法(https://groups.googl