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

Clo*_*ees 6 c++ templates llvm-clang

我试图使用clang 3.3在我的Mac上为经典的复制和交换习惯编译以下代码

template<typename T> class node{

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

public:
    friend void swap(node<T>&, node<T>&);
    // other stuff
}
Run Code Online (Sandbox Code Playgroud)

然而链接器抱怨道.我现在明白我应该将该函数声明为模板.但是,如果我遵循建议的风格,将出现的错误这里从MSDN:

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);
};
Run Code Online (Sandbox Code Playgroud)

我做了复制粘贴,但得到以下错误:

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.
Run Code Online (Sandbox Code Playgroud)

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

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

template <typename U> friend void swap(node<U>&, node<U>&);
Run Code Online (Sandbox Code Playgroud)

但是都困扰我.第一个集群的类声明,而第二个集合友谊交换采用不同的类型.

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

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>&);
};
Run Code Online (Sandbox Code Playgroud)

这也适用于铿锵声.

Bil*_*nch 7

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

#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);
}
Run Code Online (Sandbox Code Playgroud)

  • @CloudyTrees:clang用于阻止它的规则是:C ++ 2011 [temp.local]第6段:__不得在其范围内(包括嵌套范围)重新声明模板参数。模板参数的名称不得与模板名称相同。__可以在Sema ::中的[clang源代码](http://clang.llvm.org/doxygen/SemaTemplate_8cpp_source.html)中找到。 DiagnoseTemplateParameterShadow`方法。 (9认同)