C++ <;可变模板>;Visual Studio中具有默认值的模板参数编译错误
在将代码从GCC移植到MSVC时遇到了这个模糊的问题 考虑以下代码段:C++ <;可变模板>;Visual Studio中具有默认值的模板参数编译错误,c++,visual-studio,templates,variadic-templates,template-templates,C++,Visual Studio,Templates,Variadic Templates,Template Templates,在将代码从GCC移植到MSVC时遇到了这个模糊的问题 考虑以下代码段: template <typename T> struct Foo; template <template <typename...> typename Container, typename Arg> struct Foo<Container<Arg>> { using arg_t = Arg; }; template <typename X>
template <typename T>
struct Foo;
template <template <typename...> typename Container, typename Arg>
struct Foo<Container<Arg>> {
using arg_t = Arg;
};
template <typename X>
struct A {};
template <typename X, typename Y = void>
struct B {};
template <typename X, typename Y = void, typename Z = void>
struct C {};
int main() {
typename Foo<A<int>>::arg_t a;
typename Foo<B<int>>::arg_t b;
typename Foo<C<int>>::arg_t c;
return 0;
}
模板
结构Foo;
模板
结构Foo{
使用arg_t=arg;
};
模板
结构A{};
模板
结构B{};
模板
结构C{};
int main(){
typename Foo::arg\u t a;
类型名Foo::arg\u t b;
类型名Foo::arg\u t c;
返回0;
}
我们使用
Foo
trait来提取模板类的第一个参数,其中从第二个模板开始的参数具有默认值(例如,真正的用例是std::unique_ptr
)。Clang和GCC完美地处理了这个代码段,但是MSVC(Visual Studio 17附带的一个)抛出了非常明显的编译错误。结果是,GCC和Clang以某种方式处理了默认模板参数,因此Bar
接口接受了A
。另一方面,MSVC没有。不确定它是标准的还是GCC/Clang扩展。
无论如何,解决方案是添加虚拟变量参数以匹配剩余参数
template <typename T>
struct Foo;
template <template <typename...> typename Container,
typename Arg, typename... MsvcWorkaround>
struct Foo<Container<Arg, MsvcWorkaround....>> {
using arg_t = Arg;
};
template <typename X>
struct A {};
template <typename X, typename Y = void>
struct B {};
template <typename X, typename Y = void, typename Z = void>
struct C {};
int main() {
typename Foo<A<int>>::arg_t a;
typename Foo<B<int>>::arg_t b;
typename Foo<C<int>>::arg_t c;
return 0;
}
模板
结构Foo;
模板
结构Foo{
使用arg_t=arg;
};
模板
结构A{};
模板
结构B{};
模板
结构C{};
int main(){
typename Foo::arg\u t a;
类型名Foo::arg\u t b;
类型名Foo::arg\u t c;
返回0;
}
它真的很难从编译器错误中理解这个问题,而且我无法用谷歌搜索出一个解决方案,这就是为什么我想分享我的 两个注意事项:此解决方案还允许类模板具有多个非默认参数(如
std::map
),而原始代码不允许,并且不允许类模板具有默认的非类型模板,而原始代码不允许。