关键字“模板”混淆了MSVC [英] Keyword 'template' confuses MSVC

查看:59
本文介绍了关键字“模板”混淆了MSVC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于模板的哪个编译器是正确的问题之一。考虑以下内容:

One of those "which compiler is right" questions about templates. Consider following:

template<typename T>
class Container
{
public:
    template<typename V>
    class iterator;
};

template<typename T>
template<typename V>
class Container<T>::iterator
{
public:
    iterator &operator++();
};

现在为 operator ++ 提供定义时

template<typename T>
template<typename V>
typename Container<T>::template iterator<V> &Container<T>::iterator<V>::operator++()
{
    //do your thing
    return *this;
}

并确保几乎所有版本的4.8以上版本和Clang 3.2以上版本的GCC可以编译它。 MSVC19 +却没有,它特别不喜欢该定义中的 template 关键字。它抱怨说,它不能匹配声明和定义,这特别有趣,因为它给出了所要查找的内容和候选,并且两者都相同。如果删除了模板,因此仅使用 typename Container< T> :: iterator< V> ,MSVC会对其进行编译精细。但是Clang和GCC将会失败。

And sure enough pretty much any version of GCC from 4.8+ and Clang 3.2+ can compile it. MSVC19+ however does not and it specifically dislikes the template keyword in that definition. It complains that it cannot match the declaration and definition which is especially funny since it gives what it looked for and the "candidate" and they are both identical. If template is removed so only typename Container<T>::iterator<V> is used, MSVC compiles it just fine. Clang and GCC however will fail.

您可以在Compiler Explorer中尝试使用它:实时演示

You can try it live at Compiler Explorer: live demo

那么谁是对的?由于GCC和Clang都有很长一段时间了,所以我倾向于向他们倾斜。但是,我想支持所有这三个方面。所以我将其移至类内定义还是使用 #ifdef ?似乎是错误的,如果此处的MSVC错误,则应报告该错误(除非是已知问题)。

So who is right? Since both GCC and Clang has this for a long time I tend to lean towards them. However I would like to support all three. So either I move it to in-class definition or use #ifdef? Seems wrong and if MSVC is at wrong here it should be reported (unless it is a known issue).

推荐答案

使用尾随返回类型的代码。不需要 typename template

You can simplify code by using trailing return type. No need for typename or template:

template<typename T>
template<typename V>
auto Container<T>::iterator<V>::operator++() -> iterator<V> &
{
    //do your thing
    return *this;
}

在线编译器

这篇关于关键字“模板”混淆了MSVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆