2017-11-09 4 views
5

std::variant私はstd::variantというタイプのスーパーセットを持つ別のものに変換したいと思っています。それを行う方法はありますか?私は単に一方を他方に割り当てることができますか?std :: variantをスーパータイプの別のstd :: variantに変換する

template <typename ToVariant, typename FromVariant> 
ToVariant ConvertVariant(const FromVariant& from) { 
    ToVariant to = std::visit([](auto&& arg) -> ToVariant {return arg ; }, from); 
    return to; 
} 

int main() 
{ 
    std::variant<int , double> a; 
    a = 5; 
    std::variant <std::string, double, int> b; 
    b = ConvertVariant<decltype(b),decltype(a)>(a); 
    return 0; 
} 

私は単純ではなく、この複雑な鋳造セットアップを経由するよりも、変換を行うためにb = aを書くことができるようにしたいと思います。 std名前空間を汚染することなく

編集:

error C2679: binary '=': no operator found which takes a right-hand operand of type 'std::variant<int,double>' (or there is no acceptable conversion) 

note: while trying to match the argument list '(std::variant<std::string,int,double>, std::variant<int,double>)' 
+1

'U'は、すべてのタイプの宇宙であり、PはUを持っている場合、PはUに等しいではないでしょうか? 解決しようとしている問題の理解に問題があります。 – P0W

+0

'b = a'を直接コンパイルして問題を確認してください。 –

+0

エラーC2679:バイナリ '=':タイプ 'std :: variant 'の右オペランドを取る演算子が見つかりません(または受け入れ可能な変換はありません) 注:しようとしている間に引数リストに一致する '(std :: variant 、std :: variant )' – Bomaz

答えて

3

これはYakkの目のオプションの実装です。

そして、あなたはその使用を見ることができるようにするのは簡単です:

std::variant<int, char> v1 = 24; 
std::variant<int, char, bool> v2; 

v2 = variant_cast(v1); 
0

オプション:

  • operator=と建設あなたが望む方法を実装し、おそらくstd::variantから継承する独自のvariantタイプを、書くだけでb = aを書くには、次のエラーを与えます。 variantのコンストラクタは、あなたのバリアント型で正しく動作しないかもしれないSFINAEトリックを行うことができるので、いくつかの作業が行われなければなりません。そのためには、裸のusing宣言ではなく、ベースバリアントへのSFINAE転送をしたいとします。

  • 送信元/宛先の種類を指定する必要がないように、ConvertVariantを作成してください。 ConvertVariantのようなものを呼び出すoperator std::variant<Ts...>()&&を持つソースバリアントを保持するコンバーターヘルパーテンプレートタイプを返します。

    template <class... Args> 
    struct variant_cast_proxy 
    { 
        std::variant<Args...> v; 
    
        template <class... ToArgs> 
        operator std::variant<ToArgs...>() const 
        { 
         return std::visit([](auto&& arg) -> std::variant<ToArgs...> { return arg ; }, 
              v); 
        } 
    }; 
    
    template <class... Args> 
    auto variant_cast(const std::variant<Args...>& v) -> variant_cast_proxy<Args...> 
    { 
        return {v}; 
    } 
    

    あなたは、転送のセマンティクスのための微調整をすることがあります:

関連する問題