为什么一个类不能从decltype的结果中继承?

13
为什么一个类不能在继承列表中使用 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的情况下)。


3
你尝试过使用gcc 4.7、clang或其他编译器吗?gcc目前还不完全符合C++11标准... - PlasmaHH
1
@PlasmaHH 我现在正在尝试编译clang(出于其他原因),但是使用MSVC++ 2010无法工作。 - Seth Carnegie
4个回答

19

允许这样做:

10.1: "使用以下格式,在类定义中可以指定一组基类:"

class-or-decltype:
nested-name-specifieropt class-name
decltype-specifier

所以我猜你的编译器有 bug。


Eclipse CDT 也会将其报告为语法错误,但实际上它可以编译。 - WorldSEnder

10

3
一种解决方法:
template <typename T>
class ID
{
 public:
  typedef T type;
};

template<typename T>
class A : public ID<whatever>::type { };

注意,我正在从函数返回类型继承。这并不能做到相同的事情。 - Seth Carnegie
3
@Seth说:我想意思是尝试使用template<typename T> class A : public ID<decltype(std::declval<T>().hello())>::type { }; - ildjarn
而不是编写自己的类,您可以使用std::enable_if<true, decltype(...)>::type - Fozi
我认为身份变换非常重要,因此应该单独定义并用其适当的名称进行调用。 - n. m.
@n.m. Boost有它:http://www.boost.org/doc/libs/1_51_0/libs/mpl/doc/refmanual/identity.html - usta

-2

你可以尝试类似这样的东西

template<typename T>
class A : public result_of<T::hello()>

虽然这个语法可能期望一个静态成员函数,但它很可能会遇到与阻止 decltype 工作相同的错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接