请考虑以下代码:
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表现出相同的行为。
答案 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 { ... }