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 */}