C++ 如何获得const合格的declval?
考虑以下代码:C++ 如何获得const合格的declval?,c++,c++11,constants,decltype,C++,C++11,Constants,Decltype,考虑以下代码: #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())>
#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;
}
#包括
#包括
#包括
结构基
{
int f()常数;
双f();
};
结构派生
:公共基地
{
模板//修改此
T g()常数;
};
int main()
{
常数导出x;
std::cout您试图在需要完成的上下文中使用派生的
,但它还不能完成,因为它是完成定义所需的方法返回类型的一部分。编译器无法解决此循环
您需要将基类与std::declval()
一起使用,您的代码将被编译。GCC 4.8.1如下所示:
template <typename T = decltype(std::declval<Base const>().f())>
模板
您需要告诉编译器进行调用的对象是const
您不能在此declval
中指定Derived
,因为在调用时,Derived
是一个不完整的类型。此外,您甚至不需要Derived
作为declval
的一部分,因为f()
是Base
的成员将declval
抛出窗口;当类型表达式依赖于函数参数、类成员和/或此
时,几乎可以肯定的是,将其放在尾部返回类型中更容易、更清晰,您可以按名称引用它们:
struct Derived
: public Base
{
Derived() {}
auto g() const -> decltype(f());
};
我将用户提供的默认构造函数添加到Derived
中,这样const-Derived x;
就按照§8.5/6的要求格式良好。您将Derived
更改为Base
。为什么?@0x499602D2:因为在调用时,Derived
是一个不完整的类型。也不需要它,因为调用实际上是在 Base
。在这个特定的例子中,是的,它是有效的,但问题更“一般”。问题是“我如何获得一个declval哪个X”,你的答案是“不要使用declval”。已经证明OP所寻找的是可以实现的。我不能对此进行投票。@DanielFrey C++11 8.5/6“如果程序调用常量限定类型T的对象的默认初始化,则T应为具有用户提供的默认构造函数的类类型。”@JohnDibling问题是“如何修改decltype(std::declval().f())以使其返回int而不是double?”我通过删除“std::declval()”对其进行了修改。“并将其从模板参数移动到后续返回类型。这可能不是OP所期望的答案,但它确实显示了如何用更少的代码实现所需的目的。@DanielFrey依附于此。尽管问题仍然存在?或者可能在2011年重新打开。更正:问题不是“打开”,而是“起草”