c++ - MSVC 2017 - 错误 - 如何将模板类 X 的模板成员函数声明为嵌套类 X::Y 的友元

标签 c++ class templates visual-c++ nested

我正在尝试获取一个使用 GCC 编译和运行的 cmake C++ 项目,以便使用 MSVC 进行编译。我正在使用 VS 2017。

我不是代码的作者,我只是负责用 MSVC 编译它。

该项目很大,所以我不确定如何呈现 MCVE。但是,我会尽力在这里解释:

我收到这个错误:

这对应于下面 sibling_iterator 类中的 friend 声明。

但是,leftmost_output()node 的成员。

node 的定义附在下面(向下看大约 3/4):

我很确定这是 related to the bug in VS related to nested template classes因为 sibling_iteratornode 嵌套在另一个模板类中。

我的问题是如何使整个节点类成为友元而不是指定特定的成员函数?这可能会在任何其他建议中失败,这是最受欢迎的。

最佳答案

最小的可重现代码是:

#include <map>
template <class T, class T2>
struct relative_iterator : T {};

struct edge : public std::map<int, int>::iterator {};
using T_edge = edge;

class node {
public:

    template <class T_iterable, class T_content>
    class sibling_iterator : public relative_iterator<T_iterable, T_content>
    {
    public:
        friend sibling_iterator<edge, T_edge>  node::leftmost_output();
    //..
    };

    static sibling_iterator<edge, T_edge> leftmost_output();  // <--move up
} ;

有两种方法可以解决这个问题:

选项 1

移动leftmost_output()的定义以上class sibling_iterator

选项 2

制作node依赖名称。如果有别名 name这取决于 T_iterable ,那么它的查找将延迟到class sibling_iterator<T_iterable, T_contents>的时间。被实例化。最简单的方法是使用标准中的标准实用程序:

class sibling_iterator : public relative_iterator<T_iterable, T_content>
{
public:
    static constexpr bool dependent_true = std::is_same<T_iterable,T_iterable>::value;
    using dependent_node = typename std::enable_if<dependent_true, node>::type;
    friend sibling_iterator<edge, T_edge>  dependent_node::leftmost_output();
};

选项 2.5

但是,如果您更喜欢定义自己的解决方案,您可以定义一个 dependet_type<T, Dependent>助手:

template <class T, class Dependent>
struct dependent_type
{
    using type = T;
};
template <class T, class Dependent>
using dependent_type_t = typename dependent_type<T, Dependent>::type;

并使用它:

template <class T_iterable, class T_content>
class sibling_iterator : public relative_iterator<T_iterable, T_content>
{
public:
    using dependent_node = typename dependent_type<node, T_iterable>::type;
    friend sibling_iterator<edge, T_edge>  dependent_node::leftmost_output();
//..
};

我认为这是最好的选择,因为它需要对现有代码库进行较少的更改。

选项 2.5.5

我会写一个更短的变体:

friend sibling_iterator<edge, T_edge> dependent_type_t<node, T_iterable>::leftmost_output()

这看起来很完美,因为它只需要对源代码进行最少的更改。如果它没有使编译器崩溃,我会写它:

fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1469)

关于c++ - MSVC 2017 - 错误 - 如何将模板类 X 的模板成员函数声明为嵌套类 X::Y 的友元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52112588/

相关文章:

javascript - ES6 类私有(private)成员语法

javascript - 当你的模板有空格/文本节点时,WebKit 会导致 DOM 插入变慢吗?

c++ - 我需要帮助修复错误消息 - "error LNK2019: unresolved external symbol"

c++ - 将 vector 的子 vector 传递给函数

c++ - 如何在等待程序启动困惑/GTK+ 时制作加载/介绍动画弹出窗口

c++ - 你如何对每个元素执行转换并将结果附加到 C++ 中?

c++ - 模板构造函数中的模板类特化

c++ - 库中的链接时间优化

c++ - 写一个奇偶校验类。该类提供了一个名为 put 的成员函数,它计算提供的元素数。

javascript - javascript es6 中链接静态和非静态方法