C++ 英特尔C&x2B+;成员函数重载解析中的编译器错误,涉及;使用;别名 #包括 模板 结构条{}; 模板 使用Baz=棒; 结构Foo{ 模板 无效NoAlias(Bar){} 模板 无效别名(Baz){} }; 模板 void foo(Bar){} 模板 空条(条){} int main(){ //所有这些都很好 foo(Bar()); foo(Baz()); bar(bar()); bar(Baz()); Foo().NoAlias(Bar()); Foo().NoAlias(Baz()); //但这两个在ICPC(ICC)14.0.2上给出了错误: //没有函数模板“Foo::Alias”的实例与参数列表匹配 //请注意,NoAlias和Alias之间的唯一区别是(不)使用别名 //对于成员函数参数 Foo().别名(Bar()); Foo().Alias(Baz()); 返回0; }

C++ 英特尔C&x2B+;成员函数重载解析中的编译器错误,涉及;使用;别名 #包括 模板 结构条{}; 模板 使用Baz=棒; 结构Foo{ 模板 无效NoAlias(Bar){} 模板 无效别名(Baz){} }; 模板 void foo(Bar){} 模板 空条(条){} int main(){ //所有这些都很好 foo(Bar()); foo(Baz()); bar(bar()); bar(Baz()); Foo().NoAlias(Bar()); Foo().NoAlias(Baz()); //但这两个在ICPC(ICC)14.0.2上给出了错误: //没有函数模板“Foo::Alias”的实例与参数列表匹配 //请注意,NoAlias和Alias之间的唯一区别是(不)使用别名 //对于成员函数参数 Foo().别名(Bar()); Foo().Alias(Baz()); 返回0; },c++,c++11,compiler-bug,icc,C++,C++11,Compiler Bug,Icc,ICC 14.0.2给出了错误: #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...>) {

ICC 14.0.2给出了错误:

#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-std=c++11-Wall-pedantic-pthread-o.scratch{-,.}cpp&/.scratch cpp
.scratch.cpp(36):错误:没有函数模板“Foo::Alias”的实例与参数列表匹配
参数类型为:(Bar)
对象类型为:Foo
Foo().别名(Bar());
^
.scratch.cpp(37):错误:没有函数模板“Foo::Alias”的实例与参数列表匹配
参数类型为:(Baz)
对象类型为:Foo
Foo().Alias(Baz());
^
但是,它同时使用GCC4.8和Clang 3.4.2进行编译。(在64位Linux上测试。)

熟悉C++11标准的人能确认这确实是一个bug吗

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

您的示例(显然)结构良好。§14.8.2.5/9描述了在这种情况下如何进行扣除

如果
p
的表单包含
,则将相应模板参数列表
p
的每个参数
i与
a
的相应模板参数列表的相应参数
a
i进行比较。[…]. 如果
P
i是包扩展,则将
P
i的模式与
a
的模板参数列表中的每个剩余参数进行比较。每次比较都会推断出模板参数包中后续位置的模板参数,这些参数包由
P
i展开


此外,您的代码正在我的机器上以15.0.3版编译。因此,升级编译器应该可以解决这个问题。我看不出另一个简单的解决办法。

我建议你在英特尔C++论坛上提问。
$ 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>());
          ^