2017-02-28 6 views
2

Iコード例の次のコードを持っている:C++:テンプレート引数控除その他のテンプレート関数の引数としてテンプレート関数を渡す

アイデアはBoxと呼ばれ、ここでコンテナクラスがあること、そして私たちが望むかもしれないということですこのコンテナの新しいバージョンをmappingで作成して、現在の内容を超える関数を作成します。 BOX3が作成されたライン42、控除/置換が失敗したテンプレート引数で

#include <iostream> 
#include <tuple> 

template <typename TContent> 
class Box 
{ 
    TContent d_content; 

    public: 

    Box(TContent content) 
    : 
    d_content(content) 
    {} 

    TContent content() const 
    { 
    return d_content; 
    } 

    template <typename Function> 
    auto transform(Function fun) -> decltype(Box{fun(d_content)}) 
    { 
    return Box{fun(d_content)}; 
    }; 

}; 

template <typename TElem> 
std::tuple<TElem, TElem> toTuple(TElem thing) 
{ 
    std::cout << "Transforming " << thing << "to tuple.\n"; 
    return std::make_tuple(thing, thing); 
} 

int main() { 
    std::cout << "Hello World!\n"; 

    Box<int> mybox{10}; 
    Box<int> box2 = mybox.transform([](int content){ return content * 2;}); 
    std::cout << "Transformed box: " << box2.content() << '\n'; 
    Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple); // <- Template argument deduction/substitution fails here! 
    std::cout << "Transformed box: " << std::get<0>(box3.content()) << '\n'; 
} 

Try it out here

main.cpp: In function 'int main()': 
main.cpp:42:60: error: no matching function for call to 'Box<int>::transform(<unresolved overloaded function type>)' 
    Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple); 
                  ^
main.cpp:22:8: note: candidate: template<class Function> decltype (Box<TContent>{fun(((Box<TContent>*)this)->Box<TContent>::d_content)}) Box<TContent>::transform(Function) [with Function = Function; TContent = int] 
    auto transform(Function fun) -> decltype(Box{fun(d_content)}) 
     ^~~~~~~~~ 
main.cpp:22:8: note: template argument deduction/substitution failed: 
main.cpp:42:60: note: couldn't deduce template parameter 'Function' 
    Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple); 
                  ^

exit status 1 

これは、テンプレート関数を渡すためにしようとしたときにケースのようです(機能テンプレート?)を、テンプレート引数のパラメータを期待する関数に渡します。

これを避ける唯一の方法は、lambdaやその他の非テンプレート関数ですべてのテンプレート関数をラップすることです。これは多くの定型文を紹介するので、もちろん最適ではありません。

なぜこの場合に失敗テンプレート引数控除であり、作業を行いそのテンプレート引数控除を確保するために、Boxクラス(及び/又はそのtransformメンバ関数)のコードを変更する方法はありますか? repl.itまだC++ 14をサポートしていないとして

(与えられたコードは、C++ 11である。C++ 14の主な違いはtransformのトレーリング戻り型を省略することができるであろう。ここにあなたの例では、エラー、しかし、同じまま私は(のみ)にも14 C++での作業のソリューションに満足しています)

答えて

関連する問題