首页 > 解决方案 > 可变模板类型作为返回类型,MSVC 怪异

问题描述

给定以下代码:

class DummyOK {
   public:
    template <typename U, typename... Args>
    class AThing {
       public:
    };

   public:
    template <typename U, typename... Args>
    AThing<U, Args...> GetAThing();
};

template <typename U, typename... Args>
typename DummyOK::template AThing<U, Args...> DummyOK::GetAThing() {
    return AThing<U, Args...>{};
}

template <typename T>
class DummyKO {
   public:
    template <typename U, typename... Args>
    class AThing {
       public:
    };

   public:
    template <typename U, typename... Args>
    AThing<U, Args...> GetAThing();

    template <typename U, typename... Args>
    AThing<U, Args...> AnOtherGetAThing() {
        return AThing<U, Args...>{};
    }
};

template <typename T>
template <typename U, typename... Args>
typename DummyKO<T>::template AThing<U, Args...> DummyKO<T>::GetAThing() {
    return AThing<U, Args...>{};
}

int main() {
    DummyOK{}.GetAThing<char, unsigned, float>();
    DummyKO<int>{}.GetAThing<char, unsigned, float>();
    DummyKO<int>{}.AnOtherGetAThing<char, unsigned, float>();

    return 0;
}

也可以在这里找到:https ://godbolt.org/z/8747rj77K

为什么它在 clang/gcc 而不是 msvc 上编译。为什么 AnOtherGetAThing() 可以编译,但 GetAThing() 不能编译(在 msvc 上)。

msvc 返回的错误是:

<source>(39): error C2244: 'DummyKO<T>::GetAThing': unable to match function definition to an existing declaration
<source>(39): note: see declaration of 'DummyKO<T>::GetAThing'
<source>(39): note: definition
<source>(39): note: 'DummyKO<T>::AThing<U,Args...> DummyKO<T>::GetAThing(void)'
<source>(39): note: existing declarations
<source>(39): note: 'DummyKO<T>::AThing<U,Args...> DummyKO<T>::GetAThing(void)'

谢谢

标签: c++templatesvisual-c++variadic

解决方案


我会说 msvc 错误,

作为解决方法,您可以使用尾随返回类型:

template <typename T>
template <typename U, typename... Args>
auto DummyKO<T>::GetAThing() -> AThing<U, Args...>
{
    // ...
}

演示


推荐阅读