Почему это простое использование признаков SFINAE и типа для перегрузки шаблона функции приводит к неоднозначному вызову?

avatar
joaocandre
8 августа 2021 в 20:46
76
1
1

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

#include <type_traits>
#include <vector>
#include <initializer_list>

template< typename T, typename = std::enable_if< std::is_arithmetic< T >::value > >
bool myFunction(const std::vector< T >& data) {
    // ...
    return true;
}


template < typename T, typename = std::enable_if< !std::is_arithmetic< T >::value >  typename = void >
bool myFunction(const std::vector< T >& data) {
    // ...
    return true;
}


template< typename T >
bool myFunction(const std::initializer_list< T >& data) {
    return myFunction< T >(std::vector< T >(data));
}


int main(int argc, char const *argv[]) {
    std::vector< float > data = { };

    myFunction(data);  // error: call of overloaded ‘myFunction(std::vector<float>&)’ is ambiguous

    return 0;
}

Однако при попытке скомпилировать этот код я получаю сообщение об ошибке, жалующееся на неоднозначность вызова. Что именно мне здесь не хватает? Разве второй аргумент шаблона не должен гарантировать, что для любого T объявляется только один myFunction?

Источник
alter_igel
8 августа 2021 в 23:16
1

Обратите внимание, что в этом случае лучше использовать std::enable_if_t<...>* = nullptr, чем typename = std::enable_if<...>. См. coderhelper.com/q/59473453/5023438

Ответы (1)

avatar
Chris Beck
8 августа 2021 в 20:48
6

Это должно быть std::enable_if_t, а не std::enable_if. Или, поскольку вы отметили C++11, вы можете сделать std::enable_if<...>::type

std::enable_if<false> не является ошибкой замены, только std::enable_if<false>::type.

Ted Lyngmo
8 августа 2021 в 20:56
2

... и демо с этим исправлением

Ted Lyngmo
8 августа 2021 в 21:17
0

... и более чистая версия (i.m.o.)