7

您将如何在 a 中使用非类型模板参数比较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;
    }
}

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

4

2 回答 2

6

这完全取决于您想在无效代码上引发什么样的错误/失败。这是一种可能性(撇开明显的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;
    }
};
于 2013-05-18T02:57:23.527 回答
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;
    }
}
于 2013-05-18T02:58:15.283 回答