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
#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
#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