std :: declval vs crtp,无法从不完整类型推断出方法返回类型

时间:2019-06-07 16:07:26

标签: c++ c++11 decltype crtp declval

我正在尝试这样做(在c ++ 11中):

#include <utility>

template <typename T>
struct base {
    using type = decltype( std::declval<T>().foo() );
};

struct bar : base<bar> {
    int foo() { return 42;}
};

int main() {
    bar::type x;
}

失败

prog.cc: In instantiation of 'struct base<bar>':
prog.cc:8:14:   required from here
prog.cc:5:46: error: invalid use of incomplete type 'struct bar'
     using type = decltype( std::declval<T>().foo() );
                            ~~~~~~~~~~~~~~~~~~^~~
prog.cc:8:8: note: forward declaration of 'struct bar'
 struct bar : base<bar> {
        ^~~

如何在bar::foo中为base的返回类型声明别名?

这个问题似乎很相关:Special behavior for decltype of call operator for incomplete types,尽管我无法设法将给出的答案应用于我的案子。

1 个答案:

答案 0 :(得分:12)

您可以使type为模板类型别名,以便用户可以在bar的定义可用后实例化它。这会将最终语法从bar::type更改为bar::type<>

template <typename T>
struct base {
    template <typename G = T>
    using type = decltype( std::declval<G>().foo() );
};

struct bar : base<bar> {
    int foo() { return 42;}
};

int main() {
    bar::type<> x;
}

live example on godbolt.org