• 10
• 9
• 13
• 10
• 18

# Global Templated Methods

This topic is 4842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have several vector types templated in their scalar type:
template<typename Real> struct Vector3

I would like to have a global method that scales the vector on the left-hand side:
template<typename Real>
Vector3<Real> operator*(const Real, const Vector3<Real>&);

However, the compiler (MSVC++ .NET 2003) doesn't like this idea. It doesn't instantiate the operator, because for some reason, it is unaware that I would like to invoke this with Real = float or whatever. So as it stands I have to explicitly write each implementation for each type I want to use. Is there a way to remedy this situation? Tim

##### Share on other sites
Moved to General Programmming.

##### Share on other sites
Are you trying to seperate the implementation from the header where you declare the operator overload? If so, that isn't going to be happy.

Unless your compiler supports the export keyword, and MSVC doesn't, then you can't put the definition of a template in a separate source file without explicit instantiation for specific types. Without explicit instantiation, the complete definition of the template needs to be available at point of instantiation, which means, in effect, that the definition needs to go into the header. (Or an inline file of some sort, etc.)

For more details see these articles: "Export" Restrictions, Part 1 and "Export" Restrictions, Part 2.

And before petewood gets to this thread, I suppose I'll post this link for him. It's an article entitled "Instantiator: A (Mostly) Portable Framework for Separate Compilation of Templates"

If that isn't the problem, then you should give more details on what exact errors you are getting and possibly a more complete code example.

##### Share on other sites
Every compiler I tested it on (BCB 5.6.4, minGW gcc 3.3.1 & VC++ 13.10.3077 - the free version) worked fine as long as I used the correct type for the lhs:
template <typename TYPE>class Test{};template <typename TYPE>Test<TYPE> operator*(const TYPE t, const Test<TYPE>& tt){	return Test<TYPE>();}int main(){	Test<float> tf;	tf = 7.0f * tf;//	tf = 3 * tf; - error	Test<int> ti;	ti = 4 * ti;}

Quote:
 Original post by SiCraneAnd before petewood gets to this thread, I suppose I'll post this link for him. It's an article entitled "Instantiator: A (Mostly) Portable Framework for Separate Compilation of Templates"

Do you have that permenantly on your clipboard? [lol]

Enigma

##### Share on other sites
Yeah, I'm aware of the export necessities of templates.

The declaration is in the .h file. At the bottom of the .h file I include
the .inl file. The definition is in the .inl file.

I thought I had this working before, but all of a sudden it's not behaving
nicely anymore.

TT

##### Share on other sites
Aye, there's the rub!

In addition to having it declared as a global method I had it declared as a friend method of the Vector3 class. Removing that fixed it.

Thanks!

TT

##### Share on other sites
To get it to compile as a friend you need to declare the function before the class and in the class append <> to the name of the operator, like so:
template <typename TYPE>class Test;template <typename TYPE>Test<TYPE> operator*(const TYPE t, const Test<TYPE>& tt);template <typename TYPE>class Test{	public:		friend Test<TYPE> operator*<>(const TYPE t, const Test<TYPE>& tt);};template <typename TYPE>Test<TYPE> operator*(const TYPE t, const Test<TYPE>& tt){	return Test<TYPE>();}int main(){	Test<float> tf;	tf = 7.0f * tf;//	tf = 3 * tf; - error	Test<int> ti;	ti = 4 * ti;}

Fortunately GCC has a very helpful warning if you try and compile that the way you'd normally write a friend function. It actually tells you how to write it correctly! (I certainly wouldn't have had a clue otherwise).

Enigma

##### Share on other sites
Quote:
 Original post by EnigmaEvery compiler I tested it on (BCB 5.6.4, minGW gcc 3.3.1 & VC++ 13.10.3077 - the free version) worked fine as long as I used the correct type for the lhs:

	tf = 7.0f * tf;//	tf = 3 * tf; - error//      tf = ::operator*<float>(3, tf); - ok?

Just wondering if I got that right...