Подтвердить что ты не робот

Ошибка компилятора Intel С++ в разрешении перегрузки функции-члена с использованием "использования" псевдонима?

#include <cstddef>

template<typename T, T... Is>
struct Bar { };

template<size_t... Is>
using Baz = Bar<size_t, Is...>;

struct Foo {
  template<size_t... Is>
  void NoAlias(Bar<size_t, Is...>) { }

  template<size_t... Is>
  void Alias(Baz<Is...>) { }
};

template<typename T, T... Is>
void foo(Bar<T, Is...>) { }

template<size_t... Is>
void bar(Bar<size_t, Is...>) { }

int main() {
  // All these work fine
  foo(Bar<size_t, 4, 2>());
  foo(Baz<4, 2>());
  bar(Bar<size_t, 4, 2>());
  bar(Baz<4, 2>());
  Foo().NoAlias(Bar<size_t, 4, 2>());
  Foo().NoAlias(Baz<4, 2>());

  // But these two give error on ICPC (ICC) 14.0.2:
  //   no instance of function template "Foo::Alias" matches the argument list
  // Note the only difference between NoAlias and Alias is (not) using the alias
  // for the member function parameter
  Foo().Alias(Bar<size_t, 4, 2>());
  Foo().Alias(Baz<4, 2>());

  return 0;
}

ICC 14.0.2 дает ошибку:

$ icc -std=c++11 -Wall -pedantic -pthread -o .scratch{-,.}cpp && ./.scratch-cpp

.scratch.cpp(36): error: no instance of function template "Foo::Alias" matches the argument list
            argument types are: (Bar<size_t, 4UL, 2UL>)
            object type is: Foo
    Foo().Alias(Bar<size_t, 4, 2>());
          ^

.scratch.cpp(37): error: no instance of function template "Foo::Alias" matches the argument list
            argument types are: (Baz<4UL, 2UL>)
            object type is: Foo
    Foo().Alias(Baz<4, 2>());
          ^

Однако он компилируется как с GCC 4.8, так и с Clang 3.4.2. (Протестировано на 64-битном Linux.)

Может ли кто-нибудь, кто хорошо знаком со стандартом С++ 11, это действительно ошибка?

Кроме того, есть ли простой способ на основе препроцессора?

4b9b3361

Ответ 1

Ваш пример (четко) хорошо сформирован. В §14.8.2.5/9 описывается, как выполняется дедукция в этом случае.

Если P имеет форму, содержащую <T> или <i>, то каждый аргумент P i соответствующего списка аргументов шаблона P сравнивается с соответствующим аргументом A i соответствующего списка аргументов шаблона A. [...]. Если P i является расширением пакета, то образец P i сравнивается с каждым оставшимся аргументом в списке аргументов шаблона A. Каждое сравнение выводит аргументы шаблона для последующих позиций в пакетах шаблонов параметров, расширенных P i.

Кроме того, ваш код компилируется с версией 15.0.3 на моем компьютере. Следовательно, обновление компилятора должно устранить проблему. Я не вижу другого простого решения.