C++ 运算符的显式实例化>&燃气轮机;超载

C++ 运算符的显式实例化>&燃气轮机;超载,c++,templates,operator-overloading,C++,Templates,Operator Overloading,我有一个类Vector,我使用的库提供了一个类YAML::Node。我想为这两种类型重载运算符>> 我已将以下声明添加到Vector的声明中: friend void operator>>(YAML::Node const & node, Vector<T> & v); 但是,这会导致以下链接器错误: Error 9 error LNK2019: unresolved external symbol "void __cdecl operator&

我有一个类
Vector
,我使用的库提供了一个类
YAML::Node
。我想为这两种类型重载
运算符>>

我已将以下声明添加到
Vector
的声明中:

friend void operator>>(YAML::Node const & node, Vector<T> & v);
但是,这会导致以下链接器错误:

Error   9   error LNK2019: unresolved external symbol "void __cdecl operator>>(class YAML::Node const &,class Vector<double> &)" (??5@YAXAEBVNode@YAML@@AEAV?$Vector@N@@@Z) referenced in function "public: static class Scene __cdecl Scene::fromFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?fromFile@Scene@@SA?AV1@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
为什么函数的模板版本不起作用


编辑:忘记提及;编译器是Visual Studio 11 Beta,这很奇怪。我看不到任何错误,甚至MSDN文档(这是VisualC++ +右)确认模板实例化应该推断模板参数。实例化中的参数匹配。可能是因为过载的操作符坏了

尝试在其上添加显式模板参数不会有什么坏处


还有,可能是被typedef搞混了?你永远不知道!试着用double替换。

这很奇怪。我看不到任何错误,甚至MSDN文档(这是VisualC++ +右)确认模板实例化应该推断模板参数。实例化中的参数匹配。可能是因为过载的操作符坏了

尝试在其上添加显式模板参数不会有什么坏处


还有,可能是被typedef搞混了?你永远不知道!尝试替换double。

好吧,问题是您声明的
friend
是一个非模板函数,它与您的shift运算符没有任何关系。事实上,您的模板使用了编译器应该抱怨的任何私有成员。下面是一个示例,它应该是这样的:

template <typename T>
class foo
{
public:
    template <typename S>
    friend void f(foo<S>);

private:
    T value;
};

template <typename T>
void f(foo<T> v)
{
    v.value;
}
template void f(foo<int>);

int main()
{
    foo<int> v;
    f(v);
}
模板
福班
{
公众:
模板
朋友f(foo);
私人:
T值;
};
模板
无效f(foo v)
{
v、 价值观;
}
模板空白f(foo);
int main()
{
富五世,;
f(v);
}
如果您将好友声明替换为

friend void f(foo<T>);
f(foo);

这段代码也不会链接,实际上会产生一个编译时错误,表明函数
f()
不是友元。

好吧,问题是您声明的
friend
是一个非模板函数,它与您的shift运算符没有任何关系。事实上,您的模板使用了编译器应该抱怨的任何私有成员。下面是一个示例,它应该是这样的:

template <typename T>
class foo
{
public:
    template <typename S>
    friend void f(foo<S>);

private:
    T value;
};

template <typename T>
void f(foo<T> v)
{
    v.value;
}
template void f(foo<int>);

int main()
{
    foo<int> v;
    f(v);
}
模板
福班
{
公众:
模板
朋友f(foo);
私人:
T值;
};
模板
无效f(foo v)
{
v、 价值观;
}
模板空白f(foo);
int main()
{
富五世,;
f(v);
}
如果您将好友声明替换为

friend void f(foo<T>);
f(foo);

此代码也不会链接,实际上会产生一个编译时错误,表明函数
f()
不是友元。

将函数声明为
友元
不会声明函数模板;相反,类模板的每个专门化都声明了一个非模板函数,其参数类型根据模板参数重载。将选择这些模板,而不是您定义的模板;但它们没有定义,因此存在错误


要修复它,您可以在类模板之前声明函数模板(在这种情况下,友元声明将使其成为友元,而不是声明新函数),或者在类模板内内联定义友元函数,这样,类模板的每个专门化都定义了函数并声明了它。

将函数声明为
朋友
并不声明函数模板;相反,类模板的每个专门化都声明了一个非模板函数,其参数类型根据模板参数重载。将选择这些模板,而不是您定义的模板;但它们没有定义,因此存在错误


要修复它,您可以在类模板之前声明函数模板(在这种情况下,友元声明将使其成为友元,而不是声明新函数),或者在类模板内内联定义友元函数,因此,类模板的每个专门化都定义了函数并声明了它。

谢谢,现在就有意义了!谢谢,现在有道理了!
friend void f(foo<T>);