C ++ 0x decltype无法推导出成员变量constness

时间:2011-02-08 21:05:34

标签: c++ const c++11 decltype

请考虑以下代码:

template <typename T>
class B
{
};

template <typename T>
B<T> f(T& t)
{
    return B<T>();
}

class A
{
    class C {};
    C c;
public:
    A() {}

    decltype(f(c)) get_c() const { return f(c); }
};

int main()
{
    A a;
    a.get_c();
}

当我尝试编译时,我收到错误:

test.cpp: In member function 'B<A::C> A::get_c() const':
test.cpp:31:46: error: conversion from 'B<const A::C>' to non-scalar type 'B<A::C>' requested

似乎在decltype中,编译器不知道这是一个const成员函数,因此c的类型为const C,因此错误地推断出f(c)的类型1}}为B<C>而不是B<const C>,这就是它的真实含义。

我做错了什么,或者这是编译错误?我使用gcc 4.6,但4.4和4.5表现出相同的行为。

4 个答案:

答案 0 :(得分:7)

编译器根据当前的C ++ 0x WP正确运行。请参阅当前正在处理的this issue report

最终的C ++ 0x Standard可能不会在函数名之前改变返回类型中decltype应用程序的含义。您需要使用-> decltype(f(c))将其移动到参数列表之后,希望在最终的C ++ 0x中执行正确的操作。

答案 1 :(得分:0)

不,decltype不应该考虑函数是否为const,因为它不能。同样可以用不同的方式写出来:

typedef decltype(f(c)) return_type;

return_type get_c() const { return f(c); }

更正:decltype(f(c))甚至不应该编译,因为c不是静态的。

答案 2 :(得分:0)

f需要采用右值参考,而不是左值参考。

答案 3 :(得分:0)

我认为您不允许在通常无法调用的任何内容上使用decltype。我无法在标准中找到允许您访问c的任何内容,即使在decltype表达式中,也可以在任何可以使用c的地方之外。既然你没有this指针,那么我认为你可以做你想做的事情。这样做至少在MSVC 2010中不起作用,它与const无关。

我考虑使用declval来获取一个,但是你无法访问A&amp;&amp; .c,因为A在那时是一个不完整的类型。无论如何,除了类似的东西之外,我无法看到你想要做的事情:

decltype(f(declval<C const>())) get_c() const { ... }