c++ - 带有非类型模板参数的 std::enable_if

标签 c++ templates c++11

您将如何在 std::enable_if 中使用非类型模板参数比较? 我无法弄清楚如何再次执行此操作。 (我曾经有过这个工作,但我丢失了代码所以我无法回头看,我也找不到我在其中找到答案的帖子。)

预先感谢您对此主题的任何帮助。

template<int Width, int Height, typename T>
class Matrix{
    static
    typename std::enable_if<Width == Height, Matrix<Width, Height, T>>::type
    Identity(){
        Matrix ret;
        for (int y = 0; y < Width; y++){
            elements[y][y] = T(1);
        }
        return ret;
    }
}

编辑:修复了评论中指出的缺失括号。

最佳答案

这完全取决于您想在无效代码上引发哪种错误/失败。这是一种可能性(撇开明显的 static_assert(Width==Height, "not square matrix");)

(C++98 风格)

#include<type_traits>
template<int Width, int Height, typename T>
class Matrix{
public:
    template<int WDummy = Width, int HDummy = Height>
    static typename std::enable_if<WDummy == HDummy, Matrix>::type
    Identity(){
        Matrix ret;
        for (int y = 0; y < Width; y++){
        // elements[y][y] = T(1);
        }
        return ret;
    }
};

int main(){
    Matrix<5,5,double> m55;
    Matrix<4,5,double> m45; // ok
    Matrix<5,5, double> id55 = Matrix<5,5, double>::Identity(); // ok
//  Matrix<4,5, double> id45 = Matrix<4,5, double>::Identity(); // compilation error! 
//     and nice error: "no matching function for call to ‘Matrix<4, 5, double>::Identity()"
}

编辑:在 C++11 中,代码可以更紧凑和清晰,(它适用于 clang 3.2 但不适用于 gcc 4.7.1,所以我不确定它有多标准):

(C++11 风格)

template<int Width, int Height, typename T>
class Matrix{
public:
    template<typename = typename std::enable_if<Width == Height>::type>
    static Matrix
    Identity(){
        Matrix ret;
        for(int y = 0; y < Width; y++){
            // ret.elements[y][y] = T(1);
        }
        return ret;
    }
};

2020 年编辑:(C++14)

template<int Width, int Height, typename T>
class Matrix{
public:
    template<typename = std::enable_if_t<Width == Height>>
    static Matrix
    Identity()
    {
        Matrix ret;
        for(int y = 0; y < Width; y++){
        //  ret.elements[y][y] = T(1);
        }
        return ret;
    }
};

(C++20) https://godbolt.org/z/cs1MWj

template<int Width, int Height, typename T>
class Matrix{
public:
    static Matrix
    Identity()
        requires(Width == Height)
    {
        Matrix ret;
        for(int y = 0; y < Width; y++){
        //  ret.elements[y][y] = T(1);
        }
        return ret;
    }
};

关于c++ - 带有非类型模板参数的 std::enable_if,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16619931/

相关文章:

c++ - 大小由模板参数定义的成员数组,但为什么没有对零大小数组发出警告?

c++ - 模板组合和友元传递性

c++ - 如何编码要用于模板参数的类型列表?

c++ - 修改 Makefile 以支持 c++11

c++11 - 将函数向量的参数传递给 std::function 时出现问题

c++11 - C++ 11 如何通过int值获取枚举类值?

c++ - 在内联汇编中使用函数范围的标签

c++ - 快速排序线性时间?

c++ - 具有运算符重载的函数模板

c++ - 如何在我的项目中使用 FFTW DLL 导入库 .lib 作为静态 .lib?