【问题标题】:"Undefined class" as argument for is_base_of [duplicate]“未定义的类”作为 is_base_of [重复] 的参数
【发布时间】:2020-02-18 12:40:40
【问题描述】:
class Base {};

template <class T, typename = typename std::enable_if<std::is_base_of<Base, T>::value>::type>
class B {};                                                ^^^^^^^^^^ error C2139: 'A': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_base_of'

class A : public Base
{
    B<A> b;
};

显然这是不允许的。是否有解决方法,或者我忘记了什么?

【问题讨论】:

  • 我可以立即想出解决实际问题的方法,但无论哪种方式,您都希望将默认参数值更改为 typename std::enable_if&lt;...&gt;::type
  • 我为什么要这样做?
  • @T.J.Evers std::enable_if 本身永远不会退出 SFINAE,它的 type 成员会被动态禁用。
  • 另外,我原来的评论中有错字:“我可以……”应该是“我不能……”:)。
  • 当前解决方法:我们 B&lt;A, void&gt; b; 绕过检测。不漂亮,但至少它在其他地方仍然很活跃。

标签: c++ c++11 templates inheritance


【解决方案1】:

这是 GCC 的输出:

type_traits:1302:66: error: incomplete type 'A' used in type trait expression
    : public integral_constant<bool, __is_base_of(_Base, _Derived)>
                                                                 ^
<source>:5:51: note: in instantiation of template class 'std::is_base_of<Base, A>' requested here
template <class T, typename = std::enable_if<std::is_base_of<Base, T>::value>>
                                                  ^
<source>:10:5: note: in instantiation of default argument for 'B<A>' required here
    B<A> b;
    ^~~~

<source>:8:7: note: definition of 'A' is not complete until the closing '}'
class A : public Base
      ^

确实,A 是不完整的,直到达到结束 }。你在类型特征中使用A,同时在A 中实例化B&lt;A&gt;,所以你不走运。

您可以做的是在 B 的成员函数中使用 static_assert 来强制执行它:

template <class T>
class B {
public:
    B() {
        static_assert(std::is_base_of<Base, T>::value, "T must inherit from base");
    }
};

在成员函数内部,所有类型都是完整的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    • 2011-06-06
    相关资源
    最近更新 更多