3

enable_if を使用しないクラス内に、テンプレート パラメーター固有の関数を配置したいと考えています。その名前は変わりませんが、パラメーターの型は異なります (ただし、初期化されるのは 1 つだけなので、これは関係ありません)。

enum class MyCases {
    CASE1,
    CASE2
};

template<enum MyCases case>
class MyClass
{
    template<typename = typename std::enable_if<case == MyCases::CASE1>::type>
    void myFunction(ParameterTypeA a) {
        ...
    }

    template<typename = typename std::enable_if<case == MyCases::CASE2>::type>
    void myFunction(ParameterTypeB b) {
        ...
    }
};

コンパイラが最初の関数を CASE2 で、2 番目の関数を CASE1 でインスタンス化しようとしているというエラーが表示されますが、置換の失敗によってエラーが発生することはないと思いました (SFINAE)。私は何を間違っていますか?助けてくれてありがとう!

error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
4

1 に答える 1

3

これが解決策です。下にスクロールして、私の思考プロセスを確認してください。

#include <type_traits>
#include <iostream>

struct ParameterTypeA {};
struct ParameterTypeB {};

enum class MyCases {
    CASE1,
    CASE2
};

template<enum MyCases U>
class MyClass
{
public:
    MyClass() { }
    ~MyClass() { }

    template<enum MyCases T = U>
    void myFunction(ParameterTypeA a, typename std::enable_if<T == MyCases::CASE1, void>::type* = nullptr) {
        std::cout << "A" << std::endl;
    }

    template<enum MyCases T = U>
    void myFunction(ParameterTypeB b, typename std::enable_if<T == MyCases::CASE2, void>::type* = nullptr) {
        std::cout << "B" << std::endl;
    }
};

int main() {
    MyClass<MyCases::CASE1> m1;
    m1.myFunction(ParameterTypeA{});
    MyClass<MyCases::CASE2> m2;
    m2.myFunction(ParameterTypeB{});
    return 0;
}

出力:

A

B

実際の例


templateメンバー関数の前に追加しないと、error: no type named 'type' in 'struct std::enable_if<false, void>'エラーなどが発生します。正気を保つために、次の例に要約しました。

#include <type_traits>

template <typename U>
class Test {
    template <typename T = U>
    void myFunction(int b, typename std::enable_if<std::is_same<int, T>::value, void>::type* = nullptr) {
    }

    template <typename T = U>
    void myFunction(int b, typename std::enable_if<!std::is_same<int, T>::value, void>::type* = nullptr) {
    }
};

int main() {
    Test<int> test;

    return 0;
}

これに気付いた後、最初の人の答えを修正してこれを取得しました。ご覧のとおりenum class、このバージョンには no はありませんが、とをに変更するtypename Uと、魔法のように機能します。typename Tenum MyCases

#include <type_traits>
#include <iostream>

struct ParameterTypeA {};
struct ParameterTypeB {};

template<typename U>
class MyClass
{
public:
    MyClass() { }
    ~MyClass() { }

    template<typename T = U>
    void myFunction(ParameterTypeA a, typename std::enable_if<std::is_same<ParameterTypeA, T>::value, void>::type* = nullptr) {
        std::cout << "A" << std::endl;
    }

    template<typename T = U>
    void myFunction(ParameterTypeB b, typename std::enable_if<std::is_same<ParameterTypeB, T>::value, void>::type* = nullptr) {
        std::cout << "B" << std::endl;
    }
};

int main() {
    MyClass<ParameterTypeA> m1;

    m1.myFunction(ParameterTypeA{});

    MyClass<ParameterTypeB> m2;

    m2.myFunction(ParameterTypeB{});
    return 0;
}

出力:

A

B

実際の例

于 2013-11-29T16:14:02.203 に答える