有人可以解释一下我做错了什么吗?这是我从编译器得到的错误。
非常感谢
1>------ Build started: Project: Ch16, Configuration: Release Win32 ------
1> p643_inclusion.cpp
1> p643_inclusion_main.cpp
1> p643_print.cpp
1>p643_print.cpp(5): error C2065: 'T1' : undeclared identifier
1>p643_print.cpp(5): error C2065: 'T2' : undeclared identifier
1>p643_print.cpp(6): warning C4552: '<<' : operator has no effect; expected operator with side-effect
1>p643_print.cpp(7): warning C4552: '<<' : operator has no effect; expected operator with side-effect
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
p643_inclusion.h
#ifndef P643H
#define P643H
template< class T1, class T2> class Car {
friend void print (const Car<T1, T2> &c1);
private:
T1 Wheels;
T2 DriversName;
public:
Car(): Wheels(4), DriversName("None") {}
Car(T1, T2);
};
template <class T1, class T2> class Driver {
private:
T1 Name;
T2 Surname;
public:
Driver(): Name("None"), Surname("None") {}
};
#include "p643_inclusion.cpp"
#endif
p643_inclusion.cpp
# ifndef P643CC
#define P643CC
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
#include "p643_inclusion.h"
template<class T1, class T2>
Car<T1, T2>::Car(T1 w, T2 d) {
Wheels = w;
DriversName = d;
}
#endif
p643_print.cpp
#include "p643_inclusion.h"
template< class T1, class T2> class Car;
void print (const Car<T1, T2> &c1) {
cout << c1.Wheels << endl;
cout << c1.DriversName << endl;
}
主
#include "p643_inclusion.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
Car<int, string> myCar;
Driver<string, string> myDriver;
print(myCar);
return 0;
}
答案 0 :(得分:4)
您的功能实际上不是非模板功能。
void print (const Car<T1, T2> &c1) {
cout << c1.Wheels << endl;
cout << c1.DriversName << endl;
}
这是错误的。你能问问自己究竟是什么T1
?和T2
?
您应该将其实现为:
template<class T1, class T2>
void print (const Car<T1, T2> &c1) {
cout << c1.Wheels << endl;
cout << c1.DriversName << endl;
}
你应该把它friend
作为:
template< class T1, class T2> class Car {
//choose different name for type params, because enclosing class
//already using T1, and T2
template<class U, class V>
friend void print (const Car<U, V> &c1);
//...
答案 1 :(得分:2)
混合模板和友谊并不总是像看起来那么简单。我的建议是你在类定义中定义了友好函数,然后你的问题基本上会消失:
template <typename T1, typename T2>
struct test {
friend void print( test const & t ) { ... };
};
对于模板test
的每个实例化,它将声明并定义一个(非模板化的)自由函数,该函数使用触发模板实例化的相同模板参数实例化test
对象。
其他可用选项(如果可能,我会清除这些选项):
您可以将print
作为模板,并将该模板声明为您的班级模板的朋友(整个模板):
template <typename T1, typename T2>
struct test {
template <typename U, typename V>
friend void foo( test<U,V> const & ); // befriend template, all instantiations
};
template <typename T1, typename T2>
void foo( test<X,Y> const & x ) {...}
这将打开您的内部模板的所有潜在实例化,包括可能的特化,您可能不想这样做。如果你想只与该模板的特定实例建立联系,你可以这样做,但它变得更加麻烦:
template <typename T1, typename T2> struct test; // forward declaration
template <typename T1, typename T2>
void foo( test<T1,T2> const & ); // forward declaration
template <typename T1, typename T2>
struct test {
friend void foo<T1,T2>( test<T1,T2> const & ); // befriend specific instantiation
};
template <typename T1, typename T2>
void foo( test<T1,T2> const & x ) { ... } // implement
有关进一步说明,您可以查看答案here