函数模板返回类型推导

时间:2017-01-02 12:22:02

标签: c++ c++11 templates c++14

对于某些通用类型C,我有一些const课程const和非Node获取者:

template <typename NodeType>
class CParent{};

class Node {};

class C : public CParent<Node> {
    Node&       getNode(Index i);
    const Node& getNode(Index i) const;
};

现在我想创建一个别名函数,为类getNode的对象调用C

template <class CType>
NodeType& AliasGetNode(CType* cobject);

但我如何推断NodeType?即,如果我拨打AliasGetNode<const C>(c)AliasGetNode<C>(c),则NodeType应分别为const Node&Node&

我该怎么做?

我尝试了result_ofdecltype方法,但没有成功。

5 个答案:

答案 0 :(得分:19)

让编译器推导出返回类型(从C ++ 14开始):

template <class CType>
decltype(auto) AliasGetNode(CType& cobject)
{
    return cobject.getNode(0);
}

答案 1 :(得分:11)

我会推荐:

template <class CType>
auto AliasGetNode(CType& cobject) -> decltype(cobject.getNode(0))
{
    return cobject.getNode(0);
}

从c ++ 11开始,这应该可以正常工作

答案 2 :(得分:5)

定义一个简单的帮助器特征,它将根据另一个类型const从类型中添加/删除const

template <class Src, class Dst>
using copy_const = typename std::conditional<
  std::is_const<Src>::value,
  const Dst,
  typename std::remove_const<Dst>::type
>::type;

并使用它:

template <class CType>
copy_const<CType, NodeType>& AliasGetNode(CType* cobject);

答案 3 :(得分:4)

从C ++ 14开始,编译器可以推导出函数的返回类型:

template<typename CType>
decltype(auto) AliasGetNode(CType& cobject) {
    return cobject.getNode();
}

当您对AliasGetNode类型的对象发送Node时,CType会推断为Node。但是,如果您在AliasGetNode类型的对象上调用const Node,则CType会推断为const Node

AliasGetNode的返回类型设为decltype(auto)非常重要,否则您将错过返回类型的引用和常量。

答案 4 :(得分:3)

您应该编写两个别名函数,一个用于非const实例,另一个用于const实例:

template <class CType>
const NodeType& AliasGetNode(const CType* cobject) const;  // for const instance. 
// The function must be const since the only difference between return type will cause redefinition error.

template <class CType>
NodeType& AliasGetNode(CType* cobject);  // for non-const instance

如果存在重载函数,则声明为const的实例将调用const函数。当然,非const实例将调用重载函数的非const版本。例如:

class Aclass {
    public:
       string test() { return "calling non-const function"; }
       string test() const { return "calling const function"; }
};

int main() {
    Aclass a;
    const Aclass b;

    cout << a.test() << endl;
    cout << b.test() << endl;

    return 0;
}

结果将是:

calling non-const function
calling const function