【问题标题】:C2995: template already definedC2995:模板已定义
【发布时间】:2021-02-22 16:24:27
【问题描述】:

我已阅读 this question 及其答案,但仍然不明白为什么会遇到此问题。

这段代码在VS2017中编译:

#include <iostream>
#include <string>

template <class T>
struct A
{
    template<class U>
    friend std::enable_if_t<!std::is_void<U>::value, A<void>> operator&&(A<U> a1, A<void> a2)
#if 1
    ;
#else
    {
        return {};
    }
#endif

};

#if 1
template<class U>
std::enable_if_t<!std::is_void<U>::value, A<void>> operator&&(A<U> a1, A<void> a2)
{
    return {};
}
#endif

int main()
{
    std::string s;
    A<int> a1;
    A<void> a2, a3;
    
    a3 = a1 && a2;
    
    std::cout << "Press ENTER to exit.\n";
    std::getline(std::cin, s);
}

但是如果我将#if 1s 更改为#if 0s,我会得到 C2995: template function has been defined。

为什么我在struct A里面定义了friend函数编译失败,但是在外面定义却编译成功了?

【问题讨论】:

  • 也许全局中已经有一个“1”模板?尝试将“1”更改为独特的值,看看是否会产生相同的结果。

标签: c++ visual-studio sfinae friend


【解决方案1】:

标准中实际上有一条规则说这是一个错误,来自[temp.inst.3]:

但是,为了根据[basic.def.odr] 和[class.mem] 确定实例化的重新声明是否有效,与模板中的定义相对应的声明被视为定义。

标准示例:

template<typename T> struct Friendly {
  template<typename U> friend int f(U) { return sizeof(T); }
};
Friendly<char> fc;
Friendly<float> ff;  // error: produces second definition of f(U)

在您的示例中,A&lt;void&gt; 是在 A&lt;int&gt; 的实例化中实例化友元函数时实例化的。这会生成友元函数的第二个定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 2017-06-13
    • 1970-01-01
    相关资源
    最近更新 更多