gpt4 book ai didi

c++ - 相同的代码由 clang 编译但在 gcc 中失败

转载 作者:行者123 更新时间:2023-11-28 00:12:13 26 4
gpt4 key购买 nike

是我错了还是编译器错了?我试图修复以在 gcc 下编译它,但找不到方法。错误消息非常简单明了 FactorialTree<T, 0>::print是私有(private)的,但为什么 clang 可以毫无问题地接受它呢?另外,我该如何为 gcc 解决这个问题?

#include <ostream>
#include <cstring>

template<typename T, std::size_t nChildren>
class FactorialTreeBase
{
protected:
FactorialTreeBase<T, nChildren + 1> *parent;

public:
T data;

FactorialTreeBase(FactorialTreeBase<T, nChildren + 1> *p, const T &t)
: parent(p)
, data(t)
{
}

const FactorialTreeBase<T, nChildren + 1> *getParent() const
{
return parent;
}

FactorialTreeBase<T, nChildren + 1> *getParent()
{
return parent;
}

protected:
static void printIndents(std::ostream &os, std::size_t nIndents)
{
for (std::size_t i = 0; i < nIndents; ++i)
{
os << " ";
}
os << "+-";
}
};

template<typename T, std::size_t nChildren>
class FactorialTree
: public FactorialTreeBase<T, nChildren>
{
friend class FactorialTree<T, nChildren + 1>;

public:
FactorialTree<T, nChildren - 1> *children[nChildren];

FactorialTree(FactorialTree<T, nChildren + 1> *p = nullptr, const T &t = T())
: FactorialTreeBase<T, nChildren>(p, t)
{
std::memset(children, 0, nChildren * sizeof *children);
}

FactorialTree(const FactorialTree<T, nChildren> &) = delete;
FactorialTree<T, nChildren> &operator=(const FactorialTree<T, nChildren> &) = delete;
FactorialTree(FactorialTree<T, nChildren> &&) = delete;
FactorialTree<T, nChildren> &operator=(FactorialTree<T, nChildren> &&) = delete;

~FactorialTree()
{
for (std::size_t i = 0; i < nChildren; ++i)
{
if (children[i])
{
delete children[i];
}
}
}

friend std::ostream &operator<<(std::ostream &os, const FactorialTree<T, nChildren> &ft)
{
for (std::size_t i = 0; i < nChildren; ++i)
{
if (ft.children[i])
{
ft.children[i]->print(os, 0);
}
}
return os;
}

private:
void print(std::ostream &os, std::size_t nIndents) const
{
this->printIndents(os, nIndents);
os << this->data << '\n';
for (std::size_t i = 0; i < nChildren; ++i)
{
if (children[i])
{
children[i]->print(os, nIndents + 1);
}
}
}
};

template<typename T>
class FactorialTree<T, 0>
: public FactorialTreeBase<T, 0>
{
friend class FactorialTree<T, 1>;

public:
FactorialTree(FactorialTree<T, 1> *p = nullptr, const T &t = T())
: FactorialTreeBase<T, 0>(p, t)
{
}

private:
void print(std::ostream &os, std::size_t nIndents) const
{
this->printIndents(os, nIndents);
os << this->data << '\n';
}
};

#include <iostream>

enum
{
N = 3
};

template<std::size_t n>
void fillTree(FactorialTree<int, n> *ft)
{
for (std::size_t i = 0; i < n; ++i)
{
ft->children[i] = new FactorialTree<int, n - 1>;
ft->children[i]->data = i;
fillTree(ft->children[i]);
}
}

template<>
void fillTree(FactorialTree<int, 0> *)
{
}

template<std::size_t n>
void printAndCutTree(FactorialTree<int, n> *ft)
{
std::cout << *ft << '\n';
for (std::size_t i = 1; i < n; ++i)
{
delete ft->children[i];
ft->children[i] = nullptr;
}
printAndCutTree(ft->children[0]);
}

template<>
void printAndCutTree(FactorialTree<int, 0> *)
{
}

int main()
{
FactorialTree<int, N> t;
fillTree(&t);
printAndCutTree(&t);
}

最佳答案

Clang 不应该编译它。 FactorialTree<T, 0>是一个特化,在其中你不确认对 operator<< 的友元.特化不与通用案例共享代码,因此您的 operator<<看不到特化的私有(private)领域。一种解决方案是制作 operator<<一个模板然后专门化它并使它成为两者的 friend FactorialTree<T, nChildren>FactorialTree<T, 0> :

// forward declaration of the FactorialTree
template<typename T, std::size_t nChildren>
class FactorialTree;

// operator<< is now a template, rather than an overload
template<typename T, std::size_t nChildren>
std::ostream &operator<<(std::ostream &os, const FactorialTree<T, nChildren> &ft)
{
for (std::size_t i = 0; i < nChildren; ++i)
{
if (ft.children[i])
{
ft.children[i]->print(os, 0);
}
}
return os;
}

// the generic case
template<typename T, std::size_t nChildren>
class FactorialTree
: public FactorialTreeBase<T, nChildren>
{
friend class FactorialTree<T, nChildren + 1>;
// specialising operator<< and making it a friend:
friend std::ostream &operator<< <>(std::ostream &os, const FactorialTree<T, nChildren+1> &ft);
// ...
}

// the specialisation
template<typename T>
class FactorialTree<T, 0>
: public FactorialTreeBase<T, 0>
{
friend class FactorialTree<T, 1>;
// again, specialising operator<< and making it a friend
friend std::ostream &operator<< <>(std::ostream &os, const FactorialTree<T, 1> &ft);
// ...
}

关于c++ - 相同的代码由 clang 编译但在 gcc 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32445604/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com