【问题标题】:How to use decltype to determine the result of an addition如何使用 decltype 来判断加法的结果
【发布时间】:2013-06-09 20:02:49
【问题描述】:

使用decltype 我可以执行以下操作:

template <typename T1, typename T2>
auto sum(T1 const & t1, T2 const & T2)
-> decltype(t1+t2)
{ /* ... */ }

但是,在我的情况下,我需要在没有 T1T2 类型的实例的情况下找出加法的类型。具体来说:

template <typename ValueType>
class Matrix
{
    /* ... */
    public:
        template <typename CompatibleType>
        auto operator+(Matrix<CompatibleType> const & other)
        -> Matrix<decltype(ValueType+CompatibleType)>
        { /* ... */ }
};

当然,decltype(ValueType+CompatibleType) 不能这样工作。有什么办法可以实现吗?

【问题讨论】:

  • 查看std::declval

标签: c++ c++11 decltype


【解决方案1】:

使用std::declval&lt;T&gt;(); (C++11):

#include <utility>

template <typename CompatibleType>
 auto operator+(Matrix<CompatibleType> const & other)
  -> Matrix<decltype(std::declval<ValueType>() + std::declval<CompatibleType>())>
    { /* ... */ }

std::declval 返回一个右值引用,并且只能在未评估的上下文中工作,decltype 恰好是。

如果您的编译器不支持此标准,请使用此指针技巧(也仅适用于未评估上下文):

-> Matrix<decltype(*(ValueType*)(0) + *(CompatibleType*)(0))>
// or
-> Matrix<decltype(*static_cast<ValueType*>(0) +
                   *static_cast<CompatibleType*>(0))>

【讨论】:

  • 如果可以,我会标记所有三个答案,但由于我不能,我会选择提供最多信息的答案。谢谢。
  • AFAIK declval 的优势在于它适用于引用,因为从引用中创建指针是非法的。
【解决方案2】:

您可以为此使用std::declval

decltype(std::declval<A>()+std::declval<B>))

【讨论】:

    【解决方案3】:

    你需要/想要std::declval:

    decltype(std::declval<ValueType>()+std::declval<CompatibleType>());
    

    【讨论】:

      【解决方案4】:

      std::declval 有效,但隐藏在...中的更简单的答案——真正的元素访问!

      假设你的Matrix 类有一个at 函数,比如std::vector,你可以这样写

      template<typename M>
      auto operator+(M const & other)
           -> Matrix<decltype(this->at(0,0) + other.at(0,0))>
      

      否则,将at 替换为在operator+ 正文中用于访问各个元素的正确函数名称。

      这具有进一步的优势,它适用于任何提供所需访问器功能的other 参数,它根本不必是另一个Matrix&lt;T&gt;。这称为 duck typing,这就是为什么您应该使用与您的函数体实际使用的相同的访问器函数的原因。

      【讨论】:

        【解决方案5】:

        聚会有点晚了,但假设 ValueTypeCompatibleType 是 POD 类型或其他具有公共无参数构造函数的类(可能对您的用例来说是一个有效的假设),您可以构造那些类型。所以

        decltype(ValueType+CompatibleType)
        

        不起作用(如您所写)但是

        decltype(ValueType() + CompatibleType())
        

        确实如此,并且没有运行时开销(来源:here)。在这种情况下,您不需要 std::declval

        证明:Here

        【讨论】:

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