C++11:在类中查找方法和错误:嵌套名称说明符中使用的类型不完整

问题描述 投票:0回答:1

使用 C++11 中的

CRTP
习惯用法,我试图检查派生类是否具有名为
size
的方法。

#include <iostream>

template<typename Derive> struct IsContainer {
    template<typename Der> static constexpr bool has_size( decltype(&Der::size) ) { return true;  }
    template<typename Der> static constexpr bool has_size(...)                    { return false; } 
                           static constexpr bool value = has_size<Derive>(nullptr);
};

struct Container : IsContainer<Container> {
    const unsigned int size();
};

struct NonContainer : IsContainer<NonContainer> {};

int main() {
    Container obj;
    std::cout << obj.value <<std::endl;
}

然后我尝试摆脱

template <typename Der>
,如下所示:

#include <iostream>

template<typename Derive> struct IsContainer {
    static constexpr bool has_size( decltype(&Derive::size) ) { return true;  }
    static constexpr bool has_size(...)                       { return false; }
    static constexpr bool value = has_size(nullptr);
};

struct Container : IsContainer<Container> {
    const unsigned int size();
};

struct NonContainer : IsContainer<NonContainer> {};

int main() {
    Container obj;
    std::cout << obj.value <<std::endl;
}

编译错误

   In instantiation of ‘struct IsContainer<Container>’:
      error: incomplete type ‘Container’ used in nested name specifier
     |         static constexpr bool has_size( decltype(&Derive::size) ) { return true;  }
     |                                                  ^~~~~~~~

我遇到了这样一个引用自标准的语句,解释了为什么编译器会给出这个错误

3.3.2p6 声明点 [basic.scope.pdecl]

一旦声明了类成员,就可以在类范围内搜索其名称

我仍然不明白为什么第一个代码片段有效而第二个代码片段无效。如果有人向我详细解释并可能给我一个提示来解决第二个代码片段的错误,我真的很感激。

c++ c++11 templates crtp decltype
1个回答
0
投票

通过删除 template-head

template <typename Der>
,这些成员就不可能有 SFINAE,因此我们会得到一个 硬错误。 SFINAE 在模板参数替换期间发生,并且没有 template-head 就没有替换,也没有 SFINAE。

© www.soinside.com 2019 - 2024. All rights reserved.