NoneStd ::declval против crtp, не может вывести тип возврата метода из неполного типа
Я пытаюсь сделать что-то вроде этого (в 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
? Разве это не возможно?
Этот вопрос, кажется, довольно связан: специальное поведение для оператора вызова типа decltype для неполных типов, хотя мне не удалось применить ответ, приведенный там, к моему случаю.
1 ответ
Решение
Ты можешь сделать 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;
}