clang error : note: candidate constructor (the implicit move constructor) not viable:
clang error : note: candidate constructor (the implicit move constructor) not viable:
我有一个导致 clang 发出错误的以下用例。
#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);
}
错误如下
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.
使用 clang++ --std=c++11 forward.cpp
.
编译时
我在这里错过了什么?
我已经咨询了 this and this 个问题,但是它们似乎没有解决我的用例。
您忘记指定 std::enable_if
的第二个参数(默认为 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
将处于不可推导的上下文中。
你可以
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))
{}
我有一个导致 clang 发出错误的以下用例。
#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);
}
错误如下
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.
使用 clang++ --std=c++11 forward.cpp
.
我在这里错过了什么?
我已经咨询了 this and this 个问题,但是它们似乎没有解决我的用例。
您忘记指定 std::enable_if
的第二个参数(默认为 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
将处于不可推导的上下文中。
你可以
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))
{}