请考虑以下代码:
#include <iostream>
#include <type_traits>
#include <typeinfo>
struct Base
{
int f() const;
double f();
};
struct Derived
: public Base
{
template <typename T = decltype(std::declval<Derived>().f())> // Modify this
T g() const;
};
int main()
{
const Derived x;
std::cout<<typeid(decltype(x.g())).name()<<std::endl; // Prints "d", not "i"
return 0;
}
如何修改decltype(std::declval<Derived>().f())
以便它返回int
而不是double
?
我已经尝试了decltype(std::declval<const Derived>().f()
,但它没有编译。
答案 0 :(得分:7)
GCC 4.8.1喜欢这个:
template <typename T = decltype(std::declval<Base const>().f())>
您需要告诉编译器您通过其进行调用的对象是const
。
您无法在此Derived
中指定declval
,因为在通话时,Derived
是不完整的类型。此外,由于Derived
是declval
的成员,因此f()
甚至不需要Base
。
答案 1 :(得分:5)
您正试图在需要完成的上下文中使用Derived
,但它还不能完整,因为它是完成定义所需的方法返回类型的一部分。编译器无法解决此循环。
您需要将基类与std::declval<const Base>()
一起使用,您的代码将被编译。
答案 2 :(得分:0)
将declval
扔出窗外;当你的类型表达式依赖于函数参数,类成员和/或this
时,将它放在尾随返回类型中几乎肯定更容易和更清楚,你可以通过名称引用它们:
struct Derived
: public Base
{
Derived() {}
auto g() const -> decltype(f());
};
我向Derived
添加了一个用户提供的默认构造函数,以便{1 {1}}符合§8.5/ 6的要求。