std::enable_if带非类型模板参数

std::enable_if With Non-Type Template Parameters

本文关键字:类型 参数 enable if std      更新时间:2023-10-16

如何在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");)

(98年c++风格)

#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;
    }
};

EDIT 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++ 11 std::enable_if来启用…

在我的解决方案中,SFINAE发生在我的模板化返回类型中,因此使函数模板本身有效。在此过程中,函数本身也被模板化。

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