如何获得const限定的declval?

时间:2014-01-13 20:48:45

标签: c++ c++11 const 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())> // 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(),但它没有编译。

3 个答案:

答案 0 :(得分:7)

GCC 4.8.1喜欢这个:

template <typename T = decltype(std::declval<Base const>().f())> 

您需要告诉编译器您通过其进行调用的对象是const

您无法在此Derived中指定declval,因为在通话时,Derived是不完整的类型。此外,由于Deriveddeclval的成员,因此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的要求。