首页 > 解决方案 > 为嵌套模板类声明 operator==

问题描述

我在另一个模板类中有以下嵌套模板类:

template<typename T>
struct A
{
    template<typename V>
    struct B {};
};

operator==嵌套类型的非成员的签名是什么B?以下天真的尝试不起作用:

template<typename T, typename V>
bool operator==(A<T>::B<V> left, A<T>::B<V> right);

Clang、GCC 和 MSVC 给出了各种不同的错误和/或提示出了什么问题,例如缺少template关键字,但我没有尝试解决它。

请注意,这显然有效:

template<typename T>
struct A
{
    template<typename V>
    struct B {};

    template<typename V>
    friend bool operator==(B<V> left, B<V> right)
    {
        return true;
    }
};

但是,我需要非成员声明的原因是使用 qdoc 记录它。qdoc 使用 clang 来解析源代码,它要求我提供operator==我已经实际实现的声明,就像刚才显示的那样。

现场演示

标签: c++templatesclangqdoc

解决方案


错误并不算太远,因为您确实需要模板关键字,而且还需要 typename 来表示依赖类型。一个工作示例将采用以下形式:

template <typename T, typename V>
bool operator==(typename A<T>::template B<V> left,
                typename A<T>::template B<V> right) {...}

虽然我会建议:

template <typename T, typename V>
using operator_type = typename A<T>::template B<V>;

template <typename T, typename V>
bool operator==(operator_type<T, V> left,
                operator_type<T, V> right) {...}

作为减轻所需的一些深奥语法的一种手段。这是其中一件奇怪的事情,您希望 typename 足以表示 ::B 是 A 的从属名称,但您仍然需要 template 关键字,因为解析器在处理时会变得非常混乱<and >这个答案很好地解释了原因:

在名称查找 (3.4) 发现一个名称是一个模板名称后,如果这个名称后跟一个 <,则 < 总是被视为模板参数列表的开头,而不是一个名称后跟 less-比运营商。

现在我们回到与 typename 相同的问题。如果我们在解析代码时还不知道名称是否是模板怎么办?我们需要在模板名称之前插入模板,如 14.2/4 所指定。这看起来像:

t::template f<int>(); // call a function template


推荐阅读