返回值语法重载const而不是const函数

时间:2013-06-12 13:38:37

标签: c++ c++11 auto decltype

我在使用新的返回值语法为const而不是const getter函数提供正确的重载时遇到了问题。

在我的班级PhysicalNode中,我使用新的返回值语法定义了一个getter函数。这是必需的,因为getter的返回类型取决于成员的类型。

class PhysicalNode {
private:      
   solver::EnergySolver energySolver_;  ///< The energy solver of this node
   //solver::EnergyMomentumSolver energySolver_
public:
   auto getEnergySolver()-> typename 
        std::add_lvalue_reference<decltype(PhysicalNode::energySolver_)>::type;
}

但是我现在也希望将此方法作为const提供。

通常我会使用函数重载来定义我的const而不是const getter函数。

class PhysicalNode {
private:      
   solver::EnergySolver energySolver_;  
public:
   const solver::EnergySolver& getEnergySolver() const;
   solver::EnergySolver& getEnergySolver();
}

我尝试过以下函数声明,但它不起作用:

   const auto getEnergySolver() const-> typename
      std::add_lvalue_reference<decltype(PhysicalNode::energySolver_)>::type;

编译错误是:

PhysicalNode.cpp:72: error: invalid initialization of reference of type 
'std::__add_lvalue_reference_helper<LbmLib::solver::EnergySolver, true, 
false>::type {aka LbmLib::solver::EnergySolver&}' from expression of type 
'const LbmLib::solver::EnergySolver'

如何定义函数声明以将此函数定义为常量。

3 个答案:

答案 0 :(得分:4)

如果您真的想要使用此表示法和标准类型特征,则应以这种方式编写const重载:

auto getEnergySolver() const ->
    std::add_lvalue_reference<
        std::add_const<decltype(PhysicalNode::energySolver_)>::type
//      ^^^^^^^^^^^^^^
        >::type;

否则你会返回对非const的引用,这显然是错误的,因为你的成员函数是const - 合格。

请注意,此处并不真正需要类型特征(如果EnergySolver只是常规类型而不是引用类型别名):

 auto getEnergySolver()-> decltype(PhysicalNode::energySolver_)&;
 auto getEnergySolver() const -> decltype(PhysicalNode::energySolver_) const&;

但即使是decltype也是不必要的。如果您的真实程序并不比您显示的示例复杂,这就足够了:

auto getEnergySolver()-> solver::EnergySolver&;
auto getEnergySolver() const -> solver::EnergySolver const&;

答案 1 :(得分:0)

decltype(PhysicalNode::energySolver_)EnergySolver,而不是const EnergySolver,即使方法是const,因为表达式不使用this,这就是那个const限定符确实会影响。由于decltype(this->energySolver_)尚未完成,因此您无法在此上下文中使用PhysicalNode

您必须执行-> const decltype(PhysicalNode::energySolver_)&;-> std::add_lvalue_reference<std::add_const<decltype(PhysicalNode::energySolver_)>::type>::type;之类的操作。

答案 2 :(得分:0)

目前还不清楚为什么“传统”方法不适合您的目的。

使用decltype和添加/删除技巧的机制是覆盖想要过于通用的模板的基础。你必须处理未知类型和无法控制的类型。

对于通常的情况,只需添加一些typedef并直接使用它们就更清楚了。

对于你的尝试,IMO你错误地使用它,或者试试const auto&amp;在前面,或者在前面自动并在 - &gt;,combininge remove_reference之后一直组装类型,然后add_const然后add_lvalue_reference,它可能会工作,但会使头旋转。