简体   繁体   English

模板类中的模板化构造函数

[英]Templated constructors within template class

I am trying to implement a Matrix class by defining rows and columns as template parameters. 我正在尝试通过将行和列定义为模板参数来实现Matrix类。 Also, I consider the Vector as a 'degraded' matrix class that share most of its code. 另外,我将Vector视为共享其大部分代码的“降级”矩阵类。

I would like to initialize my classes using initializers lists, as it was used in old c arrays way. 我想使用初始化列表来初始化我的类,就像在旧的c数组中使用的那样。

The problem comes when trying to give one and only one constructor to the class depending of being a Matrix or a Vector, so it is forbides in compiling time to assign a matritial initializer list to a vector and a vectorial initializer list to a matrix. 当尝试根据矩阵或向量为类提供一个且仅一个构造函数时,就会出现问题,因此在编译时禁止将矩阵初始化器列表分配给向量,而将向量初始化器列表分配给矩阵。 I have tried with templates and with std::enable_if, but I am not able to fully understand the weird error messages of the compiler. 我已经尝试过使用模板和std :: enable_if,但是我无法完全理解编译器的奇怪错误消息。

I post the reduced code stating the problem, clean of all of trials to solve it. 我张贴了简化的代码来说明问题,并清除了所有试验来解决该问题。 In the comments I include further explanation of what I am trying to do. 在评论中,我进一步说明了我要做什么。 Anyone can knows how to do what I need? 任何人都可以知道该怎么做吗?

#include <initializer_list>     

template<int R, int C, typename T=int>
struct Matrix
{
    T data[R][C];

    Matrix(std::initializer_list<T> initializers) { }//Do some stuff inside
    Matrix(std::initializer_list<std::initializer_list<T>> initializers) { }//Do some stuff inside
};

template<int R, typename T=int>
using Vector = Matrix<R, 1, T>;

int main()
{
    Matrix<3, 3> m = { {1, 2, 3},
                       {4, 5, 6},
                       {7, 8, 9} };

    Vector<3> v = {10, 20, 30};

    Matrix<3, 3> m1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };//This must be avoided using templates in constructors or SFINAE 
    Vector<3> v1 = { {10, 20, 30} };//This must be avoided using templates in constructors or SFINAE

    return 0;   
}

Also, I post a coliru link with this same code: http://coliru.stacked-crooked.com/a/17b5e8c504c262d1 另外,我用相同的代码发布了一个coliru链接: http ://coliru.stacked-crooked.com/a/17b5e8c504c262d1

Thank you very much in advance. 提前非常感谢您。

With C++20, you might use requires to discards overloads: 随着C ++ 20,可以使用requires来丢弃重载:

template <int R, int C, typename T=int>
struct Matrix
{
    T data[R][C];

    Matrix(std::initializer_list<T> initializers) requires (C == 1)
    { /*..*/ }

    Matrix(std::initializer_list<std::initializer_list<T>> initializers) requires (C != 1)
    { /*..*/ }
};

Demo 演示版

Prior of that, specialization: 在此之前,专门化:

template <int R, int C, typename T=int>
struct Matrix
{
    T data[R][C];

    Matrix(std::initializer_list<std::initializer_list<T>> initializers)
    { /*..*/ }
};

template <int R, typename T>
struct Matrix<R, 1, T>
{
    T data[R][1];

    Matrix(std::initializer_list<T> initializers)
    { /*..*/ }
};

or SFINAE can be used: 或可以使用SFINAE:

template <int R, int C, typename T=int>
struct Matrix
{
    T data[R][C];

    template <typename D = C, std::enable_if_t<D == 1, int> = 0>
    Matrix(std::initializer_list<T> initializers)
    { /*..*/ }

    template <typename D = C, std::enable_if_t<D != 1, int> = 0>
    Matrix(std::initializer_list<std::initializer_list<T>> initializers)
    { /*..*/ }
};

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

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