C++11 Can';t使用SFINAE覆盖虚拟函数(std::enable_if)
下面的代码使用C++11 Can';t使用SFINAE覆盖虚拟函数(std::enable_if),c++11,virtual,sfinae,C++11,Virtual,Sfinae,下面的代码使用B::foo()覆盖覆盖虚拟A::foo()。如果未定义断开的,则它可以正常编译。我对std::enable::type的理解是,它有效地将SFINAE表达式替换为void,这应该与普通的void相同 但是,它不会编译。我发现编译器错误: 英特尔编译器(icpc): $make a cxflags=“-std=c++11-DBROKEN” icpc-std=c++11-DBROKEN a.cpp-oa a、 cpp(24):错误:不允许抽象类类型为“B”的对象: 纯虚拟函数“A::
B::foo()覆盖覆盖虚拟A::foo()
。如果未定义断开的
,则它可以正常编译。我对std::enable::type
的理解是,它有效地将SFINAE表达式替换为void
,这应该与普通的void
相同
但是,它不会编译。我发现编译器错误:
英特尔编译器(icpc):
$make a cxflags=“-std=c++11-DBROKEN”
icpc-std=c++11-DBROKEN a.cpp-oa
a、 cpp(24):错误:不允许抽象类类型为“B”的对象:
纯虚拟函数“A::foo”没有重写器
B B;
^
通用条款:
$make a cxflags=“-std=c++11-DBROKEN”CXX=g++
g++-std=c++11-DBROKEN a.cpp-oa
a、 cpp:在函数“int main()”中:
a、 cpp:24:11:错误:无法将变量“b”声明为抽象类型“b”
B B;
^
a、 cpp:9:7:注意:因为以下虚拟函数在“B”中是纯函数:
B类:A
^
a、 cpp:5:16:注意:虚拟void a::foo()
虚拟void foo()=0;
^
制造:**[a]错误1
以下是测试用例:
#include <type_traits>
class A {
public:
virtual void foo() = 0;
};
template<typename T>
class B : A
{
public:
#ifdef BROKEN
template<class Q = T>
typename std::enable_if<true>::type
#else
void
#endif
foo() override { }
};
int main()
{
B<int> b;
b.foo();
return 0;
}
#包括
甲级{
公众:
虚拟void foo()=0;
};
模板
B类:A
{
公众:
#ifdef已损坏
模板
typename std::enable_if::type
#否则
无效的
#恩迪夫
foo()重写{}
};
int main()
{
B B;
b、 foo();
返回0;
}
如果我不使用虚拟函数,那么std::enable
功能将按预期工作
补遗
这些结果适用于gcc 4.8.3。在gcc 5.3中,我额外得到一行编译器错误:
a.cpp:19:9: error: member template ‘std::enable_if<true>::type B<T>::foo()’ may not have virt-specifiers
foo() override { }
^
a.cpp:19:9:错误:成员模板“std::enable_if::type B::foo()”可能没有virt说明符
foo()重写{}
^
为什么不呢?这并不漂亮,但它完成了任务。。。使用SFINAE条件编译的虚拟重写。它有更多的调用开销(foo()
调用foo_x()
),但编译器可能会对此进行优化
#include <type_traits>
class A {
public:
virtual void foo() = 0;
};
template<typename T>
class B : A
{
public:
template<class Q = T>
typename std::enable_if<true>::type
foo_x() { }
void foo() override { foo_x(); }
};
int main()
{
B<int> b;
b.foo(); // not an example of polymorphism! just want it to compile.
return 0;
}
忘了我之前的评论吧,我没抓住要点。为了让其他读者明白,您将有多个foo\u x
方法,每个方法都带有enable\u if
,因此对于每个T
,正好有一个方法被启用,对吗?
a.cpp:19:9: error: member template ‘std::enable_if<true>::type B<T>::foo()’ may not have virt-specifiers
foo() override { }
^
#include <type_traits>
class A {
public:
virtual void foo() = 0;
};
template<typename T>
class B : A
{
public:
template<class Q = T>
typename std::enable_if<true>::type
foo_x() { }
void foo() override { foo_x(); }
};
int main()
{
B<int> b;
b.foo(); // not an example of polymorphism! just want it to compile.
return 0;
}
template<class Q = T>
typename std::enable_if<is_pod<Q>::value>::type
foo_x() { /* do something with POD */}
template<class Q = T>
typename std::enable_if<std::is_base_of<std::string,Q>::value>::type
foo_x() { /* do something with a std::string */}
template<class Q = T>
typename std::enable_if<std::is_base_of<MyCrazyClass,Q>::value>::type
foo_x() { /* do something with a derived class of MyCrazyClass */}