繁体   English   中英

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

[英]Choose correct return type of template member function

我有一个模板类,如下所示:

template <typename T, std::size_t M, std::size_t N> // MxN matrix with elements of type T
struct Mtx{...}

// component wise division
template <typename U> Mtx operator/(const Mtx<U, M, N> &rhs) const 
{ return componentDivide(*this, rhs); }

确保返回类型的函数(如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>

正如使用std::common_type在评论中提到的std::common_type应该适合你想要的。

#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

我个人倾向于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;
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM