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

时间:2022-09-16 18:53:46

With decltype I can do the following:

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

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

However, in my case I need to find out the type of an addition without having instances of the types T1 and T2. Concretely:

但是,在我的情况下,我需要找出一个加法的类型,而不需要T1和T2类型的实例。具体来说:

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

Of course, decltype(ValueType+CompatibleType) does not work this way. Is there any way I can achieve this?

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

5 个解决方案

#1


10  

Use std::declval<T>(); (C++11):

使用std :: declval (); (C ++ 11):

#include <utility>

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

std::declval returns an rvalue-reference, and will only work in an unevaluated-context, which decltype happens to be.

std :: declval返回一个rvalue-reference,并且只能在未评估的上下文中工作,而decltype恰好是。

If your compiler doesn't support this Standard, use this pointer trick (which also only works in an unevaluated-context):

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

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

#2


6  

You could use std::declval for that:

您可以使用std :: declval:

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

#3


6  

You need/want std::declval:

你需要/想要std :: declval:

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

#4


0  

std::declval works, but there's a simpler answer hiding inside the ... -- real element access!

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

Assuming your Matrix class has an at function like std::vector, you can write

假设您的Matrix类具有类似std :: vector的函数,您可以编写

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

Otherwise, replace at with the correct function name which is used inside the operator+ body to access the individual elements.

否则,请使用在operator + body中使用的正确函数名替换为访问各个元素。

This has the further advantage that it works on any other parameter which provides the needed accessor function, it doesn't have to be another Matrix<T> at all. That's called duck typing, and is why you should use the same accessor function that your function body actually uses.

这具有进一步的优点,即它适用于提供所需访问器功能的任何其他参数,它根本不必是另一个Matrix 。这就是所谓的鸭子打字,这就是为什么你应该使用你的函数体实际使用的相同的访问器函数。

#5


0  

A bit late to the party, but assuming ValueType and CompatibleType are POD types or other classes that have a public argument-free constructor (probably a valid assumption for your use-case), you can just construct those types. So

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

decltype(ValueType+CompatibleType)

does not work (as you wrote) but

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

decltype(ValueType() + CompatibleType())

does and there's no runtime overhead (Source: here). You don't need std::declval in this case.

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

Proof: Here

#1


10  

Use std::declval<T>(); (C++11):

使用std :: declval (); (C ++ 11):

#include <utility>

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

std::declval returns an rvalue-reference, and will only work in an unevaluated-context, which decltype happens to be.

std :: declval返回一个rvalue-reference,并且只能在未评估的上下文中工作,而decltype恰好是。

If your compiler doesn't support this Standard, use this pointer trick (which also only works in an unevaluated-context):

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

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

#2


6  

You could use std::declval for that:

您可以使用std :: declval:

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

#3


6  

You need/want std::declval:

你需要/想要std :: declval:

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

#4


0  

std::declval works, but there's a simpler answer hiding inside the ... -- real element access!

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

Assuming your Matrix class has an at function like std::vector, you can write

假设您的Matrix类具有类似std :: vector的函数,您可以编写

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

Otherwise, replace at with the correct function name which is used inside the operator+ body to access the individual elements.

否则,请使用在operator + body中使用的正确函数名替换为访问各个元素。

This has the further advantage that it works on any other parameter which provides the needed accessor function, it doesn't have to be another Matrix<T> at all. That's called duck typing, and is why you should use the same accessor function that your function body actually uses.

这具有进一步的优点,即它适用于提供所需访问器功能的任何其他参数,它根本不必是另一个Matrix 。这就是所谓的鸭子打字,这就是为什么你应该使用你的函数体实际使用的相同的访问器函数。

#5


0  

A bit late to the party, but assuming ValueType and CompatibleType are POD types or other classes that have a public argument-free constructor (probably a valid assumption for your use-case), you can just construct those types. So

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

decltype(ValueType+CompatibleType)

does not work (as you wrote) but

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

decltype(ValueType() + CompatibleType())

does and there's no runtime overhead (Source: here). You don't need std::declval in this case.

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

Proof: Here