【问题标题】:Constructing a mixin based on variadic templates by forwarding constructor parameters通过转发构造函数参数构造基于可变参数模板的mixin
【发布时间】:2017-01-16 12:17:04
【问题描述】:

我正在尝试构建一个 mixin 模板,其基础都作为可变参数模板参数传递。我想通过将每个mixin类的构造函数参数作为参数传递给可变参数模板构造函数来构造mixin

当使用每个 mixin 类类型的对象调用时,可变参数模板构造函数编译。但是如果我传递每个mixin类的构造函数参数(所有类都有一个参数构造函数),它不会编译

我正在使用带有 -std=c++1z 的 gcc 7.0

我做错了什么?

 #include <vector>
 #include <string>
 #include <unordered_map>
 #include <iostream>

 template < typename... T >
 struct Mixin : T...
 {
     Mixin() = delete;
     Mixin(Mixin const &) = delete;
     Mixin(Mixin &&) = delete;

     template < typename... U >
     Mixin(U &&... v) : T(std::forward < U >(v))...
     {
     }
 };

 int main()
 {
     using A = std::vector < std::string >;
     using B = std::unordered_map < std::string, std::string >;
     using C = std::string;
     using M = Mixin < A, B, C >;

     //  This doesn't compile
     M m1{{"hello", "world"}, { {"hello",  "world" }, {"world",  "hello"} }, "hello"};

     //  This compiles
     A a({"hello", "world"}); B b({ {"hello",  "world" }, {"world",  "hello"} }); C c("hello");
     M m2{a, b, c};
 }

【问题讨论】:

  • 一个主要问题(尽管与您的问题无关)是标准容器(和std::string)并不是真正设计用于继承的。他们没有虚拟析构函数。
  • 编译错误是...?
  • “它无法编译” 继续……

标签: c++ c++11


【解决方案1】:

这里的问题是std::initializer_list 不能从forwarding-reference 中推导出来。事实上,显式指定 std::initializer_list 会使您的代码编译:

M m1{
    std::initializer_list<std::string>{"hello", "world"}, 
    std::initializer_list<std::pair<const std::string, std::string>>{{"hello",  "world" },{"world",  "hello"} }, 
    "hello"};

wandbox example

您可以找到更多关于std::initializer_list和扣减in this question的信息。


您可以通过创建帮助器make_il 函数来强制扣除std::initializer_list

template <typename... Ts>
auto make_il(Ts&&... xs) 
{ 
    return std::initializer_list<std::common_type_t<Ts...>>{
        std::forward<Ts>(xs)...}; 
}

您的最终代码将如下所示:

using namespace std::literals::string_literals;          
using kvp = std::pair<const std::string, std::string>;

M m1{
    make_il("hello"s, "world"s), 
    make_il(kvp("hello"s,  "world"s), kvp("world"s,  "hello"s)), 
    "hello"};

wandbox example

【讨论】:

    猜你喜欢
    • 2016-09-02
    • 2018-05-18
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    相关资源
    最近更新 更多