具有基于受保护的基类方法的返回类型的函数

时间:2014-01-03 00:24:33

标签: c++ templates c++11

我试图让doSomeMethod()的返回类型与基类中的operator()相同,但如果它被声明为protected,则编译器会使用error: no type named 'type' in 'std::result_of'拒绝代码。如果它是公开的,它可以工作,但我想知道我是否可以让它在受保护的情况下工作。

这是复制错误的简单代码。

#include <type_traits>

class base
{
protected:
    int operator()(){return 1;};
};

class child : private base
{
    auto static doSomeMethod()
            -> typename std::result_of<base()>::type
    {
        return 1;
    }
};

编辑:

好的,感谢Kerrek SB和DietmarKühlr提供的解决方案和解释。在使用它之后,我发现这个解决方案更具可读性(至少在我的实际情况中,child是模板类,base其模板参数之一)更可靠。 但它似乎有点违背你的解释。或者仅仅是std::result_of<>在这种情况下被打破的方式?

#include <type_traits>

class base
{
protected:
    double operator()(){ return 1; };
    int operator()(int i){ return i; };
};

class child : private base 
{
  public:
    auto operator()()
      -> decltype(base::operator()()) 
    {
        return base::operator()();
    }

  auto operator()(int i)
      -> decltype(base::operator()(std::declval<int>())) 
    {
         return base::operator()(i);
    }
};

感谢您的时间。

2 个答案:

答案 0 :(得分:4)

如果您的代码字面意思是这样,那么您可以利用operator()base中受保护的child也可以在template <typename> struct memfn_result; template <typename C, typename R, typename ...Args> struct memfn_result<R (C::*)(Args...)> { using type = R; }; class base { protected: int operator()(){ return 1; }; }; class child : private base { memfn_result<decltype(&child::operator())>::type a; // "a" is an "int" }; 中使用这一事实,并使用一个简单的特征:

{{1}}

答案 1 :(得分:3)

由于base::operator()()protected而你在base类型的对象上使用它而不是child类型的对象,所以你显然无法访问该成员!您需要使用类型为child的对象访问函数调用运算符。遗憾的是,child在您尝试访问它的上下文中是不完整的,即您需要间接:

class child
    : private base {
    auto static doSomeMethod()
        -> decltype((std::declval<base>().*(&child::operator()))()) {
        return 1;
    }
};