【问题标题】:Return value syntax overloading const and not const function返回值语法重载 const 而不是 const 函数
【发布时间】:2013-06-08 15:44:16
【问题描述】:

我在使用新的返回值语法为 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'

我需要如何定义函数声明才能将此函数定义为常量。

【问题讨论】:

  • 你为什么使用typenamePhysicalNode 是类模板吗?
  • 因为我没有让 decltype 工作。但是由于您的回答,我现在知道如何避免这种情况:)
  • 好的,很高兴它有帮助:)

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


【解决方案1】:

decltype(PhysicalNode::energySolver_) 是普通的EnergySolver,而不是const EnergySolver,即使方法是const,因为表达式不使用this,这是const 限定符真正影响的。而且你不能在这种情况下使用decltype(this-&gt;energySolver_),因为PhysicalNode还没有完成。

您必须执行-&gt; const decltype(PhysicalNode::energySolver_)&amp;;-&gt; std::add_lvalue_reference&lt;std::add_const&lt;decltype(PhysicalNode::energySolver_)&gt;::type&gt;::type; 之类的操作,或者介于两者之间。

【讨论】:

    【解决方案2】:

    如果你真的想使用这个符号和标准类型特征,你应该这样写你的const重载:

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

    否则您将返回对非const 的引用,考虑到您的成员函数是const-qualified,这显然是错误的。

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

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

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

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

    【讨论】:

    • 以这种方式声明 getter 有什么好处?似乎过于复杂
    • @paulm:在这种具体情况下没有任何好处,我猜 OP 只是想尝试这种新语法
    【解决方案3】:

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

    使用 decltype 和添加/删除技巧的诡计是为希望过于通用的模板提供掩护。您必须处理未知类型和您无法控制的类型。

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

    对于您的尝试,IMO 您错误地使用了它,要么在前面尝试 const auto&,要么在前面尝试 auto 并在 -> 之后一直组装类型,结合 remove_reference,然后 add_const 然后 add_lvalue_reference,它可能会起作用,尽管会让人头晕目眩。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      相关资源
      最近更新 更多