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

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

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

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>

最佳答案

正如@Someprogrammerdude 在使用 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

关于c++ - 选择正确的模板成员函数的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53494940/

相关文章:

c++ - 在 C ://上使用 C++ 中的树命令

c++ - 将自己的类的实例传递给另一个

java - 如何让MatchAllFilter正常工作并向MatchAllfilter添加其他过滤器?

c++ - 如何使用具有串行执行顺序的 C++ 线程池

c++ - 为什么没有 to_string(const string&)?

c++ - C++中最随机的函数是什么?

c++ - 链接库 C++ 的问题

c++ - 无法在 GCC 中使用数组

Java Class.newInstance 错误

c++ - 调用 std::map::emplace() 并避免不必要的构造