简体   繁体   English

如何防止模板类的实例化?

[英]How do I prevent a instantiation of a template class?

I'm working on a templated matrix class and currently working on the template determinant function. 我正在研究模板化的矩阵类,目前正在研究模板的行列式函数。 It's a recursive function that finds the determinate of each sub matrix all the way down to the base case and adds/subtracts each of these sub determinate's together. 这是一个递归函数,可找到每个子矩阵的确定值直至基本情况,并将每个子确定值相加/相减。 Here's the function: 功能如下:

//Determinant - Only square matrices have a determinant
template <typename T, std::size_t size>
T Determinant(Matrix<T, size, size> &mat)
{
    ASSERT(size >= 2, "Wtf? 1x1 matrix?")

    T determinant = {};

    //Base case - Smallest size of matrix we can calculate the determinant is 2x2
    if (size == 2)
    {
        return ((mat.m_data[0][0] * mat.m_data[1][1]) - (mat.m_data[0][1] * mat.m_data[1][0]));
    }
    else //otherwise, we need to grab the sub matrix within the current matrix and get the determinate of those. 
    {
        Matrix<T, size - 1, size -1 > subMatrix;

        //Note: We're filling in the new sub matrix column order
        for (int topRow_ColumnIndex = 0; topRow_ColumnIndex < size; ++topRow_ColumnIndex)
        {
            int newSubCol = 0;
            for (int subCol = 0; subCol < size; ++subCol)
            {
                int newSubRow = 0;

                if (subCol == topRow_ColumnIndex)
                {
                    continue;
                }

                //Sub matrices will start one row below the top row.
                for (int subRow = 1; subRow < size; ++subRow)
                {
                    subMatrix[newSubCol][newSubRow] = mat[subCol][subRow];
                    ++newSubRow;
                }
                ++newSubCol;
            }
            determinant = determinant + (T)pow(-1, topRow_ColumnIndex) * mat.m_data[topRow_ColumnIndex][0] *Determinant(subMatrix);
        }
    }
    return determinant;
}

The issue I'm having is with the template portion of this. 我遇到的问题与此模板部分有关。 Specifically this part of the code: 具体来说,这部分代码:

Matrix<T, size - 1, size - 1 > subMatrix;

What this is intended to do is to create a matrix with dimensions that fit the sub matrix (which is 1 less than the current). 这样做的目的是创建一个尺寸适合子矩阵(比当前小1)的矩阵。

What's happening is that this specific template is being instantiated: 发生的事情是正在实例化此特定模板:

Matrix<float, 0, 0> 

which is a no go since the underlying data in the matrix is an array, and we can't have zero length arrays. 这是不可行的,因为矩阵中的基础数据是一个数组,而且我们不能有零长度的数组。

1) Is there any way to prevent this specific template from being instantiated? 1)有什么方法可以防止实例化此特定模板?

2) Possibly a stupid question but I'm calling this function with a Matrix3x3 passed in. Why does the compiler instantiate every template with a dimension of 3 all the way down to 0? 2)可能是一个愚蠢的问题,但我使用传入的Matrix3x3调用此函数。为什么编译器实例化尺寸为3一直到0的每个模板? (A low level explanation would be great if possible) (如果可能的话,低级的解释会很好)

You can specialize Determinant<T, 1> so it doesn't create Matrix<T, 0, 0> . 您可以专门处理Determinant<T, 1>因此它不会创建Matrix<T, 0, 0>

template <typename T>
T Determinant<T, 1> (Matrix<T, 1, 1> &mat) {
    // Implementation here
    // Avoid Matrix<T, 0, 0>
}

You can also specialize Determinant<T, 2> so you can drop the if else inside, since checking for template variables is better done at compile time. 您还可以专用于Determinant<T, 2>因此可以将if else内部,因为在编译时检查模板变量更好。

template <typename T, std::size_t size>
T Determinant<T, size> (Matrix<T, size, size> &mat) {
    // original "else" part here
}

template <typename T>
T Determinant<T, 2> (Matrix<T, 2, 2> &mat) {
    return ((mat.m_data[0][0] * mat.m_data[1][1]) - (mat.m_data[0][1] * mat.m_data[1][0]));
}

如果可以访问C ++ 17,则可以使用if constexpr而不是常规if来实例化“废弃”分支:

if constexpr (size == 2)

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

相关问题 如何将模板实例化声明为班级的朋友? - How do I declare a template instantiation as a friend of my class? 防止使用不完整类型实例化模板类 - Prevent instantiation of template class with an incomplete type 如何防止模板函数的隐式实例化 - How to prevent implicit instantiation of a template function 如何防止非专业模板实例化? - How to prevent non-specialized template instantiation? 使用`extern template`来防止模板类的隐式实例化 - Using `extern template` to prevent implicit instantiation of a template class 我应该如何为DLL使用此模板函数显式实例化? - How should I do this template function explicit instantiation for DLL use? 如何在模板实例化中强制将 char[] 转换为 char*? - How do I force conversion char[] to char* in template instantiation? 防止隐式模板实例化 - Prevent implicit template instantiation 我们如何在模板类中使用静态映射,在模板类的每个实例化中都应使用相同的映射 - How do we use static map in template class, with every instantiation of template class the same map should be used 如何在满足特定条件时阻止C ++模板类方法的实例化? - How to prevent instantiation of a C++ template class method when a specific condition is met?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM