комбинация enable_if + std :: less + sizeof ... приводит к сбою MSVC - PullRequest
7 голосов
/ 04 июля 2019

Вот чрезвычайно простой код:

template <typename... Args,
 typename std::enable_if<std::less<int>()(sizeof...(Args), 3), int>::type* = nullptr>
void test(std::tuple<Args...>)
{

}

int main()
{
    test(std::make_tuple(1, 2));
}

Это просто простой шаблон функции с некоторым условием enable_if. (для дальнейшего SFINAE).

Но не удается скомпилировать в Visual Studio 2019 с настройкой C ++ 17 .

error C2672:  'test': no matching overloaded function found
error C2783:  'void test(std::tuple<_Types...>)': could not deduce template argument for '__formal'

Однако я обнаружил, что хорошо компилируется в GCC и Clang . Почему этот, казалось бы, невинный код терпит неудачу?

Забавно, если я подставлю sizeof...(Args) на 2, тогда это вдруг сработает.

Редактировать : Мой оригинальный вопрос не предоставляет тип в enable_if, но я обнаружил, что void* не допускается как параметр шаблона нетипичного типа в C ++ 17. Но это не имеет значения. Потому что даже если я перейду на std::enable_if<std::less<int>()(sizeof...(Args), 3), int>, , он все равно завершится с той же ошибкой.

1 Ответ

3 голосов
/ 04 июля 2019

за [сравнение.less] :

template <class T = void> struct less {
  constexpr bool operator()(const T& x, const T& y) const;
};

constexpr bool operator()(const T& x, const T& y) const;

Возвращает: x < y.

Оператор constexpr. Таким образом, ваш код в порядке less.

Однако, технически говоря, MSVC на самом деле прямо здесь & mdash; нетипичные параметры шаблона не должны иметь тип void* в C ++ 17. MSVC фактически диагностировал это. Во всяком случае, это чисто совпадение.

Вы можете использовать < непосредственно в качестве обходного пути:

template <typename... Args,
  typename std::enable_if<(sizeof...(Args) < 3), int>::type = 0>
void test(std::tuple<Args...>)

(Обратите внимание, что вместо void* используется int, так что педанту языка абсолютно нечего сказать.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...