Can somebody explain me what I am doing wrong? This is teh error I get from the compiler.
Many Thanks
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;
}
main
#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;
}
Your function is not actually a non-template function.
void print (const Car<T1, T2> &c1) {
cout << c1.Wheels << endl;
cout << c1.DriversName << endl;
}
This is wrong. Can you ask yourself what exactly is T1
? and T2
?
You should implement this as:
template<class T1, class T2>
void print (const Car<T1, T2> &c1) {
cout << c1.Wheels << endl;
cout << c1.DriversName << endl;
}
And you should make it friend
as:
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);
//...
Mixing templates and friendship is not always as simple as it might seem. My advice is that you define the befriended function in the class definition, and then your problem will basically go away:
template <typename T1, typename T2>
struct test {
friend void print( test const & t ) { ... };
};
For each instantiation of the template test
, it will declare and define a (non templated) free function that takes a test
object instantiated with the same template arguments that triggered the instantiation of the template.
Other options available (I would stay clear of these if possible):
You can make print
be a template and declare that template a friend of your class template (the whole template):
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 ) {...}
This opens your internals to all of the potential instantiations of the template, including possible specializations, and you might not want to do that. If you want to befriend only a particular instantiation of that template, you can do so, but it becomes more cumbersome:
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
For a further explanation, you can look at the answer here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.