2017-01-16 6 views
3

バリデーションテンプレートパラメータとしてベースがすべて渡されている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}; 
} 
+0

一つの大きな問題は(無関係あなたの質問に)標準的な容器です(と 'std :: string')は実際に継承されるようには設計されていません。彼らは仮想デストラクタを持っていません。 –

+1

コンパイラのエラーは...? – max66

+1

_ "コンパイルしません" _続行... –

答えて

2

ここでの問題は、std::initializer_list転送-参照から推定することができないということです。実際には、明示的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

関連する問題