шаблон C++ enable_if не может сопоставить определение функции с существующим объявлением

Я пытаюсь определить функцию-член шаблона для класса шаблона вне класса, а также использовать SFINAE для эффективной частичной перегрузки функции. Минимальный пример того, что я пытаюсь сделать:

Тест.ч:

template<typename T, size_t D>
class Test
{
public:
    Test(){}
    ~Test(){}

    template<size_t W = D, typename = int*>
    void do_something(Test&);
private:
    T data[D];
};

#include <type_traits>

template<typename T, size_t D>
template<size_t W, typename std::enable_if<W == 2, int>::type* = 0>
inline void Test<T, D>::do_something(Test &)
{
    exit(2);
}

template<typename T, size_t D>
template<size_t W, typename std::enable_if<W == 3, int>::type* = 0>
inline void Test<T, D>::do_something(Test &)
{
    exit(3);
}

Основной.cpp:

int main(int, char**) {
    Test<float, 2> t1;
    Test<float, 2> t2;
    t1.do_something(t2);
    return 0;
}

Однако этот пример кода выдает ошибку: C2244 'Test::do_something': невозможно сопоставить определение функции с существующим объявлением. Если я изменюсь

template<size_t W, typename std::enable_if<W == 2, int>::type* = 0>

to

 template<size_t W, typename Type>

и удалите другое определение do_something, тогда код скомпилируется без проблем, поэтому я знаю, что проблема в enable_if. Итак, вопрос: как использовать enable_if для достижения эффекта частичной перегрузки без определения функции внутри класса?

Должен добавить, что я компилирую с помощью MSVS 2015.


person Grahalt    schedule 15.07.2016    source источник
comment
Вы должны использовать std::enable_if также в объявлении.   -  person Jarod42    schedule 15.07.2016
comment
Итак, в вашем случае вы можете просто использовать перегрузки.   -  person Jarod42    schedule 15.07.2016


Ответы (1)


Вы должны использовать std::enable_if также в объявлении:

template<typename T, std::size_t D>
class Test
{
public:
    template<std::size_t W, typename std::enable_if<W == 2>::type* = nullptr>
    void do_something(Test<T, W> &);

    template<std::size_t W, typename std::enable_if<W == 3>::type* = nullptr>
    void do_something(Test<T, W> &);
};



template<typename T, std::size_t D>
template<std::size_t W, typename std::enable_if<W == 2>::type*>
void Test<T, D>::do_something(Test<T, W> &)
{
    std::cout << 1 << std::endl;
}

template<typename T, std::size_t D>
template<std::size_t W, typename std::enable_if<W == 3>::type*>
void Test<T, D>::do_something(Test<T, W> &)
{
    std::cout << 2 << std::endl;
}

Демо

person Jarod42    schedule 15.07.2016