如何使用带有const重载成员函数的result_of

时间:2018-02-19 11:58:24

标签: c++ typetraits

有没有办法让result_of使用const重载的成员函数? cppreference中演示的常规方法不起作用,因为无法解析重载函数的地址。

#include <type_traits>

class C {
public:
   auto& f () { return x_; }
   const auto& f() const { return x_; }
private:
   int x_;
};

using FRet = std::result_of_t<decltype(&C::f)(C)>;

Wandbox

2 个答案:

答案 0 :(得分:7)

在这种情况下不要使用result_of - 您必须手动消除歧义歧义。您只需使用decltypestd::declval

即可
using FRet = decltype(std::declval<C>().f());

如果您想点击const重载,请使用:

using FRet = decltype(std::declval<const C>().f());

答案 1 :(得分:3)

问题实际上不在于std::result_of,因为它的所有特性。问题是将decltype应用于重载集。有充分理由这是模棱两可的。如果我们要在显式或隐含目标类型的上下文中编写&C::f,则会解析它。但是当我们试图推断出东西时,自然没有目标类型。

但是,不要感到绝望 。我们可以做的只是添加一个间接层。将过载集提升到仿函数中,并将类型特征应用于 。应用配方看起来有点像:

class FRetHelper {
    static constexpr auto lifter = [](auto&& a) -> decltype(auto) {
        return std::forward<decltype(a)>(a).f();
    };

public:
    using FRet = std::result_of_t<decltype(lifter)(C)>;
};

using FRet = FRetHelper::FRet;

Live on Wandbox。主要的警告是它需要或更晚(对于constexpr lambda)。这也意味着,我们不应该使用result_of_t。但是,哦,好吧。