2016-05-06 1 views
1

clangにエラーが発生する原因となっている次の使用例があります。 clang++ --std=c++11 forward.cppでコンパイルするときclang error:注:候補コンストラクタ(暗黙的なムーブコンストラクタ)が実行可能でない:

forward.cpp:35:12: error: no matching constructor for initialization of 'Holder' 
    Holder h(b); 
     ^~ 
forward.cpp:18:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'B' to 'const Holder' for 1st argument 
class Holder 
    ^
forward.cpp:18:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'B' to 'Holder' for 1st argument 
class Holder 
    ^
forward.cpp:21:9: note: candidate template ignored: couldn't infer template argument 'T' 
     Holder(typename std::enable_if<!std::is_same<T,A>::value 
     ^
1 error generated. 

を次のように

#include <iostream> 
#include <type_traits> 

class A 
{ 
    public: 
     int x; 
     A(int g):x(g){} 
}; 

class B : public A 
{ 
    public: 
     int y; 
     B(int p):A(p),y(p) {} 
}; 

class Holder 
{ 
    template<typename T> 
     Holder(typename std::enable_if<!std::is_same<T,A>::value 
        && std::is_base_of< A , T>::value >::type&& val) 
     : b (std::forward<T>(val)) 
     {} 


    private: 
     B b; 
}; 

int main() 
{ 
    B b(10); 

    Holder h(b); 
} 

エラーです。

私はここで何が欠けていますか?

私はすでにthisthisの質問に相談しましたが、私のユースケースは解決していないようです。

+1

を行うことができます。コンパイラはTを推論することはできません。 – MikeMB

+2

[非推論コンテキスト](http://stackoverflow.com/questions/25245453/what-is-a-nondeduced-context?lq=1)を読むと、コンパイラは「B」から「T」を推論することができない。 –

答えて

3

あなたは(voidデフォルト)

template<typename T> 
Holder(typename std::enable_if<!std::is_same<T, A>::value 
       && std::is_base_of< A , T>::value, T>::type&& val) 
    : b (std::forward<T>(val)) 
    {} 

しかし、いずれにせよ、Tは非演繹コンテキストになりstd::enable_ifの2番目のパラメータを指定することを忘れ。 あなたは重要なメッセージが最後のものである

template<typename T> 
Holder(T&& val, 
     typename std::enable_if<!std::is_same<typename std::decay<T>::type, A>::value 
           && std::is_base_of<A, typename std::decay<T>::type>::value, 
           std::nullptr_t>::type = nullptr) 
    : b (std::forward<T>(val)) 
    {} 

または

template<typename T, 
     typename std::enable_if<!std::is_same<typename std::decay<T>::type, A>::value 
           && std::is_base_of<A, typename std::decay<T>::type>::value, 
           std::nullptr_t>::type = nullptr> 
Holder(T&& val) 
    : b (std::forward<T>(val)) 
    {} 
関連する問題