选择模板成员函数的正确返回类型

时间:2018-11-27 07:46:26

标签: c++ class c++11 templates return-type

我有一个看起来像这样的模板类:

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));

2 个答案:

答案 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;
    }
};