C2995:模板已定义
C2995: template already defined
我已经阅读了 及其答案,但仍然不明白为什么我会遇到这个问题。
此代码在 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 1
s 更改为 #if 0
s,我得到 C2995:模板函数已经被定义。
为什么在struct A
内部定义友元函数编译失败,而在外部定义却编译成功?
实际上标准中有一条规则说这是一个错误,来自[temp.inst.3]:
However, for the purpose of determining whether an instantiated redeclaration is valid according to [basic.def.odr] and [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition.
标准示例:
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<void>
是在A<int>
的实例化中实例化友元函数时实例化的。这会生成友元函数的第二个定义。
我已经阅读了
此代码在 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 1
s 更改为 #if 0
s,我得到 C2995:模板函数已经被定义。
为什么在struct A
内部定义友元函数编译失败,而在外部定义却编译成功?
实际上标准中有一条规则说这是一个错误,来自[temp.inst.3]:
However, for the purpose of determining whether an instantiated redeclaration is valid according to [basic.def.odr] and [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition.
标准示例:
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<void>
是在A<int>
的实例化中实例化友元函数时实例化的。这会生成友元函数的第二个定义。