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年重新打开。更正:问题不是“打开”,而是“起草”