我有一个看起来像这样的模板类:
operator /
确保诸如Mtx<float> * Mtx<unsigned> = Mtx<float>
Mtx<float> * Mtx<int> = Mtx<float>
Mtx<float> * Mtx<double> = Mtx<double>
Mtx<double> * Mtx<float> = Mtx<double>
Mtx<short> * Mtx<int> = Mtx<int>
之类的函数的返回类型为“正确”的最佳方法是什么?
例如:
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
(int) TimeUnit.SECONDS.toMillis(185),
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
答案 0 :(得分:3)
使用std::common_type
的注释中提到的@Someprogrammerdude应该可以满足您的需求。
#include <iostream>
#include <type_traits>
template <typename T> struct Mtx
{
T _var;
template <typename U>
Mtx<std::common_type_t<T, U>> operator/(const Mtx<U> &rhs) const
{
return this->_var/rhs._var;
}
};
int main()
{
Mtx<float> fObj{ 1.02f };
Mtx<unsigned> uObj{ 1 };
Mtx<int> iObj{ 1 };
Mtx<double> dObj{ 1.02 };
Mtx<short> sObj{ 1 };
std::cout << std::boolalpha
<< std::is_same_v< decltype(fObj / uObj), Mtx<float>> << '\n' // Mtx<float> * Mtx<unsigned> = Mtx<float>
<< std::is_same_v< decltype(fObj / iObj), Mtx<float>> << '\n' // Mtx<float> * Mtx<int> = Mtx<float>
<< std::is_same_v< decltype(fObj / dObj), Mtx<double>> << '\n' // Mtx<float> * Mtx<double> = Mtx<double>
<< std::is_same_v< decltype(dObj / fObj), Mtx<double>> << '\n' // Mtx<double> * Mtx<float> = Mtx<double>
<< std::is_same_v< decltype(sObj / iObj), Mtx<int>> << '\n'; // Mtx<short> * Mtx<int> = Mtx<int>
return 0;
}
输出:
true
true
true
true
true
答案 1 :(得分:2)
我个人倾向于使用decltype(std::declval<T>() / std::declval<U>())
而不是std::common_type
,因为它明确选择了反映实际除法的类型。
因此:
template <typename T>
struct Mtx
{
T _var;
template <typename U>
Mtx<decltype(std::declval<T>() / std::declval<U>())>
operator / (const Mtx<U> &rhs) const
{
return this->_var / rhs._var;
}
};
或者,通过使用尾随返回类型,我们可以用参数的类型来表达它:
template <typename T>
struct Mtx
{
T _var;
template <typename U>
auto operator / (const Mtx<U> &rhs) const
-> Mtx<decltype(this->_var / rhs._var)>
{
return this->_var / rhs._var;
}
};