Почему класс не может наследовать от результата decltype?
Почему класс не может иметь decltype
в списке наследования? Например, я ожидаю, что следующий код сделает A<B>
наследовать от RType
, но с g++ 4.6.1 (используя -std=c++0x
) он не скомпилируется:
#include <type_traits>
template<typename T>
class A : public decltype(std::declval<T>().hello()) { };
class RType { };
class B {
public:
RType hello() { return RType(); }
};
int main() {
A<B> a;
}
Он дает следующий результат:
test.cpp:6:18: error: expected class-name before 'decltype'
test.cpp:6:18: error: expected '{' before 'decltype'
test.cpp:6:54: error: expected unqualified-id before '{' token
test.cpp: In function 'int main()':
test.cpp:16:7: error: aggregate 'A<B> a' has incomplete type and cannot be defined
Использование declval
заключается в том, чтобы предоставить экземпляр, где вам нужно было использовать decltype
, но другие использования decltype
также не выполняются (то есть без declval
).
Ответы
Ответ 1
Это разрешено:
10.1: "Список базовых классов может быть указан в определении класса с использованием обозначения:"
class-or-decltype:
nested-name-specifieropt class-name
decltype-specifier
поэтому я предполагаю, что ваш компилятор имеет ошибку
Ответ 2
Похоже на ошибку в GCC. Попробуйте 4.7.
Ответ 3
Обходной путь:
template <typename T>
class ID
{
public:
typedef T type;
};
template<typename T>
class A : public ID<whatever>::type { };
Ответ 4
Вы можете попробовать что-то вроде
template<typename T>
class A : public result_of<T::hello()>
хотя он может ожидать статическую функцию-член для этого синтаксиса, и он, скорее всего, столкнется с той же ошибкой, которая предотвратит работу decltype.