std :: enable_if使用非类型模板参数

时间:2013-05-18 01:41:50

标签: 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;
    }
}

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

2 个答案:

答案 0 :(得分:4)

这完全取决于您希望在无效代码上引发的错误/失败类型。这是一种可能性(撇开显而易见的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<Width, Height, T> >::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<Width, Height, T>
        Identity(){
        Matrix ret;
        for (int y = 0; y < Width; y++){
       //     ret.elements[y][y] = T(1);
        }
        return ret;
    }
};

答案 1 :(得分:1)

我在这里找到了我的问题的答案:Using C++11 std::enable_if to enable...

在我的解决方案中,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;
    }
}