【问题标题】:Variadic templated type as return type, MSVC weirdness可变参数模板类型作为返回类型,MSVC 怪异
【发布时间】:2021-12-17 00:05:54
【问题描述】:

给定以下代码:

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)'

谢谢

【问题讨论】:

  • 有了这个版本:godbolt.org/z/W66nvfG15clang 抱怨:/
  • 但是 msvc 编译..
  • @EtienneM:哪个 MSVC 版本?过去,MSVC 在两阶段名称查找方面存在问题。
  • @MSalters 他的例子在最新的 MSVC 上失败了:godbolt.org/z/zWj85s8cG

标签: c++ templates visual-c++ variadic


【解决方案1】:

我会说 msvc 错误,

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

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

Demo

【讨论】:

  • 我认为这也是一个错误。我尝试使用这样的自动+尾随返回类型:template &lt;typename T&gt; template &lt;typename U, typename... Args&gt; auto DummyKO&lt;T&gt;::GetAThing() -&gt; typename DummyKO&lt;T&gt;::template AThing&lt;U, Args...&gt; { return AThing&lt;U, Args...&gt;{}; } 请注意,我使用了 typename 和 ::template。使用该语法,msvc 怪癖再次出现。那么我的问题是:为什么你的语法(没有类型名/模板)是有效的 c++,如果这就是为什么当我不使用尾随返回类型时我需要编写类型名/模板。
  • DummyKO&lt;T&gt;::GetAThing 之前,您处于全局/命名空间范围内,而不是类范围内,因此您需要一个内部类型(这是依赖的,所以typename/template 用法) .之后,我们在类范围内,所以不需要在前面加上类名;但如果我们这样做,内部类将再次依赖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2023-02-05
  • 1970-01-01
相关资源
最近更新 更多