template parameters with default value compilation error in Visual Studio

问题描述 投票:2回答:1

将代码从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>
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 trait来提取模板类的第一个参数,其中从第二个模板参数开始具有默认值(实际用例例如使用std::unique_ptr)。 Clang和GCC完美地处理了这个片段,但是MSVC(Visual Studio 17附带的那个)引发了非常不明显的编译错误。

c++ visual-studio templates variadic-templates template-templates
1个回答
2
投票

原来,GCC和Clang以某种方式处理默认模板参数,因此A<X, Y=void><template <typename...> typename Bar, typename X> Bar<X>接口接受。另一方面,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;
}

从编译器错误中理解问题真的很难,我无法谷歌解决方案,这就是我想分享我的原因。

© www.soinside.com 2019 - 2024. All rights reserved.