4

有了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)这种方式行不通。有什么办法可以做到这一点?

4

5 回答 5

10

使用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))>
于 2013-06-09T20:04:22.293 回答
6

您可以std::declval为此使用:

decltype(std::declval<A>()+std::declval<B>))
于 2013-06-09T20:04:19.883 回答
6

你需要/想要std::declval

decltype(std::declval<ValueType>()+std::declval<CompatibleType>());
于 2013-06-09T20:04:28.770 回答
0

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

于 2013-09-06T22:03:14.093 回答
0

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

decltype(ValueType+CompatibleType)

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

decltype(ValueType() + CompatibleType())

没有运行时开销(来源:here)。std::declval在这种情况下你不需要。

证明:这里

于 2017-10-01T14:07:44.577 回答