c++ - Clang VS VC++ :"error: declaration of ' T'阴影模板参数”

标签 c++ templates llvm-clang

我正在尝试为 the classic copy&swap idiom 编译以下代码在我的 Mac 上使用 clang 3.3

template<typename T> class node{

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

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

然而链接器却报错了。我现在明白我应该将函数声明为模板。但是,如果我按照建议的样式进行操作,则会发生错误 here来自 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);
};

我做了复制粘贴,但出现了以下错误:

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.

这是 clang 错误吗? MSDN 网站建议它在 VC++ 下工作。

PS:我知道有两种解决方法:像Stackoverflow文章中那样在模板类中定义友元函数,或者在模板类中声明如下:

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。

最佳答案

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

#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);
}

关于c++ - Clang VS VC++ :"error: declaration of ' T'阴影模板参数”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20875033/

相关文章:

c++ - 如何在全局范围内添加包含路径到 clang

c++ - 为什么加 "const"就解决了 "invalid operands to binary expression"

c++ - 模板基类类型定义和函数的更好 C++ 语法?

c# - Process.Start 功能

C++ 使用函数参数类型进行模板参数推导

c++ - 没有匹配的函数可供调用

c++ - 重载 + 运算符以添加 2 个多项式 C++

c++ - 实例化和未实例化模板的部分模板特化

c++ - 加载 LLVM 插件时 undefined symbol

linux-kernel - 如何从内核树中构建 BPF 程序