C++ VS2013因可变模板专门化而失败

C++ VS2013因可变模板专门化而失败,c++,visual-c++,c++11,variadic-templates,C++,Visual C++,C++11,Variadic Templates,这段代码在g++和Clang中运行良好: template <typename Sig, Sig& S> struct OpF; template <typename TR, typename ... Ts, TR (&f)(Ts...)> struct OpF<TR (Ts...), f> { }; int foo(int x) { return 0; } OpF<int (int), foo> f; 哪一个有问题?这

这段代码在g++和Clang中运行良好:

template <typename Sig, Sig& S> struct OpF;

template <typename TR, typename ... Ts, TR (&f)(Ts...)>
struct OpF<TR (Ts...), f> {
};

int foo(int x) {
  return 0;
}

OpF<int (int), foo> f;
哪一个有问题?

这不是错误(在VC++中),变量列表后面有一个备用模板参数。这是无效的C++ 11。
看起来像是GCC和CLang中的一个bug。

这是VS2013编译器中的一个bug,现在似乎已经修复了。有关解决方法,请参阅:。但是,由于VS2013编译器中的另一个错误,您的代码可能仍然无法编译,这导致它将模板参数
TR(&f)(Ts…)
解析为
TR(&f)(void)
。不过,这方面也有解决办法。您可以使用嵌套类,然后该类可以使用参数包。例如:

template <typename Sig> struct OpF;

template <typename TR, typename ... Ts>
struct OpF<TR (Ts...)> {
  template <TR (&f)(Ts...)>
  struct Fn {
  };
};

int foo(int x) {
  return 0;
}

OpF<int (int)>::Fn<foo> f;
模板结构OpF;
模板
结构OpF{
模板
结构Fn{
};
};
intfoo(intx){
返回0;
}
OpF::Fn-f;

模板声明中不允许参数包后的模板参数。但是,Clang和GCC确实允许在模板专门化中使用它。因此,可能是Clang和GCC对C++11规范过于开放。

将其报告为一个bug,而他们仍有可能修复它。谢谢。我没有MS帐户,我不会把我的个人资料给他们,所以我没有错误报告。原始代码对我来说是有效的。第二个声明是第一个声明的部分专门化,并且
OpF
与该专门化匹配:
TR=int
Ts..={int}
f=::foo
@aschepler抱歉,未能在5分钟内正确格式化,应该已读取。。。我不同意,标准(或至少2012年1月的工作草案)将以下示例列为无效:
template struct static_array;//错误:值有效地扩展了同一模板参数列表中的模板类型参数//pack T
,这就是专门化中发生的情况。我认为(但不完全确定,希望可以回答)模板专门化本身必须是有效的template.PS。仍然无法正确格式化换行符,抱歉。
template <typename Sig> struct OpF;

template <typename TR, typename ... Ts>
struct OpF<TR (Ts...)> {
  template <TR (&f)(Ts...)>
  struct Fn {
  };
};

int foo(int x) {
  return 0;
}

OpF<int (int)>::Fn<foo> f;