Clang VS VC ++:“错误:'T'阴影模板参数的声明”

时间:2014-01-02 01:17:05

标签: c++ templates llvm-clang

我正在尝试使用clang 3.3

在我的Mac上为the classic copy&swap idiom编译以下代码
template<typename T> class node{

private:
    node<T>* left;
    node<T>* right;
    T value;

public:
    friend void swap(node<T>&, node<T>&);
    // other stuff
}

然而,链接器抱怨道。我现在明白我应该将该函数声明为模板。但是,如果我按照MSDN中建议here的样式发生错误:

template <class T> class Array {
    T* array;
    int size;

public:template<class T>
    //...
    template <class T>
    friend Array<T>* combine(Array<T>& a1, Array<T>& a2);
};

我进行了复制粘贴但出现以下错误:

te.cpp:33:19: error: declaration of 'T' shadows template parameter
template<class T>
               ^
te.cpp:4:17: note: template parameter is declared here
template <class T> class Array {
                ^
1 error generated.

这是一个铿锵的bug吗? MSDN网站建议它在VC ++下运行。

PS:我知道有两种解决方案:在Stackoverflow文章中定义模板类中的friend函数,或者在模板类中以下列方式声明:

template <typename U> friend void swap(node<U>&, node<U>&);

但两个都困扰我。第一个聚类是类的声明,而第二个授予友谊交换采用不同的类型。

更新:第三种解决方案是使用具有专业化的前向声明:

template <typename T> class node;
template <typename T> void swap (node<T>&, node<T>&);
template <typename T> class node{
    //...
    friend void swap<> (node<T>&, node<T>&);
};

这也适用于clang。

1 个答案:

答案 0 :(得分:6)

我相信这就是你想要的(恰好是你刚刚添加到你的问题中的第三个选项)

#include <utility>

template <typename T> class node;
template <typename T> void swap(node<T> & a, node<T> & b);

template<typename T> class node {
    private:
        node<T>* left;
        node<T>* right;
        T value;

    public:
        friend void swap<>(node<T>&, node<T>&);
};

template <typename T> void swap(node<T> & a, node<T> & b) {
    std::swap(a.left, b.left);
    std::swap(a.right, b.right);
    std::swap(a.value, b.value);
}

int main() {
    node<int> x, y;
    swap(x, y);
}