开发者

C++0x decltype fails to deduce member variable constness

Consider the following code:

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();
}

When I try to compile this, I get the error:

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

It seems that in the decltype, the compiler doesn't know that thi开发者_如何学Gos is a const member function and therefore c is of type const C, and as a result incorrectly deduces the type of f(c) to be B<C> rather than B<const C> which is what it really is.

Am I doing something incorrectly, or is this a compiler bug? I use gcc 4.6, but 4.4 and 4.5 exhibit the same behaviour.


The compiler operates correctly according to the current C++0x WP. See this issue report, which is currently being worked on.

Possibly the final C++0x Standard won't change the meaning of your decltype application in the return type before the function name. You would need to move it to after the parameter list using -> decltype(f(c)), which hopefully will do The Right thing in final C++0x.


No, decltype is not supposed to take into account whether the function is const or not, because it can't. The same could have been written differently:

typedef decltype(f(c)) return_type;

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

Correction: decltype(f(c)) shouldn't even compile, because c is not static.


f needs to take an rvalue reference, not an lvalue reference.


I don't think you're allowed to use decltype on anything you wouldn't normally be able to call. I haven't been able to find anything in the standard that would allow you to access c, even within a decltype expression, outside of anywhere you could use c. Since you don't have a this pointer at the point you're trying to do your thing, I don't think you can do what you're trying to do. Doing so doesn't work in MSVC 2010 at least, and it has nothing to do with const.

I considered using declval to get one but you can't access A&&.c because A is an incomplete type at that point. I can't see anyway to do what you're trying to do other than something like so:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜