7

で型以外のテンプレート パラメータの比較をどのように使用します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

それはすべて、無効なコードで発生させたいエラー/失敗の種類によって異なります。ここに1つの可能性があります(明らかなことは脇に置きます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()"
}

EDIT: 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 に答える