2015-09-07 80 views
0

是我还是编译器出错?我试图做一个修复,以获得这个编译下gcc,但无法找到一种方法。错误信息非常简单,FactorialTree<T, 0>::print是私人的,但为什么是铿锵接受它没有问题?另外,我怎样才能解决这个gcc?相同的代码由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); 
} 
+3

你应该修剪下来的代码,它包括了很多不相关的线。 –

回答

3

铛不应该编译这个。 FactorialTree<T, 0>是一种专业化,并且在其中您不确认operator<<的友谊。专业化不会与通用案例共享代码,因此您的operator<<无法查看专业化的专用字段。一种解决方法是让operator<<模板,然后专门它,使得它在这两个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); 
    // ... 
} 
+0

您的解决方案适用于海湾合作委员会,但现在无法在铛...'/tmp/a-696a74.o:在功能\'无效printAndCutTree <1u>(FactorialTree *)': a.cpp :(text._Z15printAndCutTreeILj1EEvP13FactorialTreeIiXT_EE [_Z15printAndCutTreeILj1EEvP13FactorialTreeIiXT_EE ] + 0x1d):未定义的引用\ operator <<(std :: ostream&,FactorialTree const&)'' – xiver77

+0

更新了答案,编译为3.4 –

相关问题