成员函数重载决议涉及"使用"别名的英特尔C++编译器错误?

eol*_*old 13 c++ icc compiler-bug c++11

#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;
}
Run Code Online (Sandbox Code Playgroud)

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>());
          ^
Run Code Online (Sandbox Code Playgroud)

但是,它与GCC 4.8和Clang 3.4.2一起编译.(在64位Linux上测试过.)

任何熟悉C++ 11标准的人都能确认这确实是一个错误吗?

此外,是否有一个简单的基于预处理器的解决方法?

Col*_*mbo 2

你的例子(显然)格式良好。\xc2\xa714.8.2.5/9 描述了在这种情况下如何执行推导。

\n\n
\n

如果具有包含或 的P形式,则将相应模板参数列表的每个参数i与 的相应模板参数列表的相应参数i进行比较。[\xe2\x80\xa6]。如果i是包扩展,则将i的模式与 的模板参数列表中的每个剩余参数进行比较。每次比较都会推导出由i扩展的模板参数包中后续位置的模板参数。<T><i>PPAAPPAP

\n
\n\n

此外,您的代码在我的机器上使用版本 15.0.3 进行编译。因此升级编译器应该可以解决这个问题。我看不到另一个简单的解决方法。

\n