Template arguments

My templated function look as follows:
1
2
3
4
5
template <typename MatTypeOne, typename MatTypeTwo>
void funct(MatTypeOne& m1, MatTypeTwo& m2) {
     //here I would need to check whether m1 and m2 are of the same "type",
     //meaning that MatTypeOne is the same as MatTypeTwo
}

What is the way to check whether m1 and m2 belong to same/different types?
Thanks
Do you need them to be of the same type?
Say I have the function funct. Usually, I invoke the function with same types (meaning MatTypeOne is the same as MatTypeTwo).
Clearly, this might be achieved with only one template argument, but I want to invoke the same function with different template arguments (and when they are different, I want to execute a few additional lines).
How to achieve this?
Okay, you can use RTTI by including the header #include <typeinfo>
1
2
3
4
5
6
7
8
9
10
11
#include <typeinfo>

template <typename MatTypeOne, typename MatTypeTwo>
void funct(MatTypeOne& m1, MatTypeTwo& m2) {
	if(typeid(MatTypeOne) != typeid(MatTypeTwo))
	{
		std::cout << "different stuff" << std::endl;
	}
	std::cout << "general stuff" << std::endl;
}
Thanks.
Template specialization could be useful here too:
Another way to do it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
using namespace std;

template <class T1, class T2>
void func(T1 t1, T2 t2)
{
    cout << "general stuff" << endl;
    type_stuff(t1,t2);
}

template <class T1, class T2>
void type_stuff(T1 t1, T2 t2)
{
    cout << "different type stuff" << endl;
}

template <class T>
void type_stuff(T t1, T t2)
{
    cout << "same type stuff" << endl;
}

int main()
{
    func(char(),double());

    cout << endl;

    func(int(),int());

    cout << "\nhit enter to quit...";
    cin.get();
    return 0;
}
Last edited on
Thanks. I'll try that.
What's wrong with

1
2
3
4
template< typename T >
void funct( const T& matOne, const T& matTwo )
{
}

?
Nothing. But this is not what he wants :P

onako wrote:
Clearly, this might be achieved with only one template argument, but I want to invoke the same function with different template arguments (and when they are different, I want to execute a few additional lines).
How to achieve this?

Galik wrote something that does the type checking in run-time and I thought I should add something that does it in compile-time. After all, it's good to have a variety of solutions to choose from :D

EDIT: OR... Did you mean, what's wrong with this:

1
2
3
4
5
6
7
8
9
10
11
template <class T1, class T2>
void func(T1 t1, T2 t2)
{
    cout << "different type stuff" << endl;
}

template <class T>
void func(T t1, T t2)
{
    cout << "same type stuff" << endl;
}

?

Again, nothing. I just thought he could factor out common code so that he doesn't have to write it in both functions.
Last edited on
Ok, then your solution I think almost works. There is ambiguity when T1 == T2.

I think you need to specialize

1
2
3
4
5
6
7
8
9
template< typename T1, typename T2 >
void func( T1& matOne, T2& matTwo )
{
}

template< typename T >
void func<T, T>( T& matOne, T& matTwo )
{
}

Oh, I thought that the compiler was smart enough to tell that I specialize just from the argument types... It compiled fine here (gcc)... But, anyway, I'll fix it.

EDIT: LOL... It refuses to compile it when I specialize explicitly... Give me some time...
Last edited on
Ok, check this out -> http://www.gotw.ca/publications/mill17.htm

It explains why you can't specialize function templates.
No, it doesn't... It just explains when it is necessary to do it and when it's not.

EDIT: The rules of choosing which function will be called:

Finally, let's focus on function templates only and consider the overloading rules to see which ones get called in different situations. The rules are pretty simple, at least at a high level, and can be expressed as a classic two-class system:

-> Nontemplate functions are first-class citizens. A plain old nontemplate function that matches the parameter types as well as any function template will be selected over an otherwise-just-as-good function template.

-> If there are no first-class citizens to choose from that are at least as good, then function base templates as the second-class citizens get consulted next. Which function base template gets selected depends on which matches best and is the "most specialized" (important note: this use of "specialized" oddly enough has nothing to do with template specializations; it's just an unfortunate colloquialism) according to a set of fairly arcane rules:

-> If it's clear that there's one "most specialized" function base template, that one gets used. If that base template happens to be specialized for the types being used, the specialization will get used, otherwise the base template instantiated with the correct types will be used.

-> Else if there's a tie for the "most specialized" function base template, the call is ambiguous because the compiler can't decide which is a better match. The programmer will have to do something to qualify the call and say which one is wanted.

-> Else if there's no function base template that can be made to match, the call is bad and the programmer will have to fix the code.
Last edited on
Ok, I figured that there's a problem in partially specializing a function template. A guy on bytes had the same problem, and the answer was to wrap the function in a struct: a struct inside the function and partially specialize that struct:

http://bytes.com/topic/c/answers/61482-partial-specialization-function-template

But, why does my solution work? And, does it work? I mean, it works ok for me, I tested it, but does it work on every compiler? The link I gave above only mentions 'fully' specialized function templates, so I don't know if I can use those rules to get an answer here...

EDIT: I guess I could too wrap it in a struct inside to be sure, but why does it work as it is now?

EDIT 2: Ok, I think I got it. The above rules don't have to do with template specialization.

(important note: this use of "specialized" oddly enough has nothing to do with template specializations; it's just an unfortunate colloquialism)

They are just rules to select which base template fits better to the situation. And I don't do any specialization (if I did, it would be partial and I would end up with an error) as I claim to do (I'll go scratch that). I just offer two base templates and these rules make sure the right one is called in every case. Ok, I think it's pretty clear now.
Last edited on
Yes, it's annoying that function templates can't be specialized. The best you can do
is wrap in a functor.

I can't see how the compiler could determine which function to call if T1 == T2, unless
the compiler has rules to match the function with fewer template parameters first.
Weird.
Topic archived. No new replies allowed.