如何使用decltype来确定加法的结果

How to use decltype to determine the result of an addition

本文关键字:结果 何使用 decltype      更新时间:2023-10-16

使用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<T>(); (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))>

您可以使用std::declval:

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

你需要/想要std::declval:

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

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<T> 。这就是所谓的鸭子类型,这就是为什么应该使用与函数体实际使用的相同的访问器函数。

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

decltype(ValueType+CompatibleType)

不工作(如你所写),但

decltype(ValueType() + CompatibleType())

可以,而且没有运行时开销(来源:这里)。在这种情况下,您不需要std::declval

证明: