calling non-template version

Hello all,

I am having problem causing non-template function to be called.

I want the minD with two parameters to be called for integer values and I want non-template minD to be called for char* type. Also want all those changed to be made inside the minD with three parameters. I mean how can I cause the non-template method and templated methods to be called for integers and char* and be by only changing the minD method (the one with three parameters)?


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
template <typename T>
const T &minD(T const& a, T const& b)
{
	if (a > b)
	{
		return b;
	}
	else
	{
		return a;
	}
}

char *minD(char * a, char * b)
{
	if (strcmp(a, b) > 0)
	{
		return b;
	}
	else
	{
		return a;
	}
}

template <typename T>
const T &minD(T const &a, T const &b, T const &c)
{
	return minD(minD(a, b), c);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{



	int val = 0;
	val = minD(42, 7, 68);
	
      const char *  const s0 = "CSC";
      const char *  const s1 = "461";
      const char *  const s2 = "This is test";
	
	const char *s = 0;
	s = minD(s0, s1, s2);

}





Last edited on
You'd probably have to do some ugly const_cast magic. I don't suggest it.

What about changing your functions to something like:
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
35
36
37
38
39
40
41
42
43
44
#include <cstring>
#include <iostream>

template <typename T>
const T &minD(T const& a, T const& b)
{
	if (a > b)
	{
		return b;
	}
	else
	{
		return a;
	}
}

const char *minD(const char * a, const char * b)
{
	std::cout << "(in strcmp minD)\n";
	if (strcmp(a, b) > 0)
	{
		return b;
	}
	else
	{
		return a;
	}
}

template <typename T>
const T * minD(T const * a, T const * b, T const * c)
{
	return minD(minD(a, b), c);
}

int main()
{
	const char * const s0 = "CSC";
	const char * const s1 = "461";
	const char * const s2 = "Optimized C++";
	
	const char *s = minD(s0, s1, s2);
	std::cout << s << '\n';
}
Last edited on
Thank you for your reply.

Then it doesn't work for the following. how can I cause the non-template method and templated methods to be called for char* and integers respectively by only changing the minD method (the one with three parameters)?

1
2
int val = 0;
val = minD(42, 7, 68);

Where one declares:

1
2
3
4
5
6
7
8
9
10
11
const char *minD(const char * a, const char * b)
{
	if (strcmp(a, b) > 0)
	{
		return b;
	}
	else
	{
		return a;
	}
}


Then this version of minD is called in your last line example.



This doesn't directly answer your question, but also consider just using something like std::min_element instead of a bunch of DIY templating.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <algorithm>
#include <cstring>
#include <iostream>

bool string_less_than(const char* a, const char* b)
{
    return strcmp(a, b) < 0;
}

int main()
{
    const char *  const s0 = "CSC";
    const char *  const s1 = "461";
    const char *  const s2 = "Optimized C++";
      
    const char * const arr[] = {s0, s1, s2}; 
    const char * min = *std::min_element(arr + 0, arr + 3, string_less_than); 

    std::cout << min << '\n';

    int arr2[] = {42, 7, 68};
    std::cout << *std::min_element(arr2 + 0, arr2 + 3) << '\n';
}

461
7
Last edited on
I just want to change minD with three parameters so I could run the code below. The one you suggested is causing " minD(42, 7, 68)" to be broken. I want "minD(42, 7, 68)" to trigger template minD and 'minD(s0, s1, s2)' to trigger non-template minD


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{



	int val = 0;
	val = minD(42, 7, 68);
	
      const char *  const s0 = "CSC";
      const char *  const s1 = "461";
      const char *  const s2 = "This is test";
	
	const char *s = 0;
	s = minD(s0, s1, s2);

}

Last edited on
I can't use STL
There's probably a clever way to do with just one template definition using conditional template parameters, but is this acceptable? I know it's two different templates so it doesn't match exactly with what you were saying.

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <cstring>
#include <iostream>

template <typename T>
const T &minD(T const& a, T const& b)
{
    std::cout << "(in T const& minD)\n";
	if (a > b)
	{
		return b;
	}
	else
	{
		return a;
	}
}

const char *minD(const char * a, const char * b)
{
	std::cout << "(in strcmp minD)\n";
	if (strcmp(a, b) > 0)
	{
		return b;
	}
	else
	{
		return a;
	}
}

template <typename T>
const T * minD(T const * a, T const * b, T const * c)
{
	return minD(minD(a, b), c);
}

template <typename T>
const T &minD(T const &a, T const &b, T const &c)
{
	return minD(minD(a, b), c);
}

int main()
{
	const char * const s0 = "CSC";
	const char * const s1 = "461";
	const char * const s2 = "Optimized C++";
	
	const char *s = minD(s0, s1, s2);
	std::cout << s << '\n';
	
	int val = minD(42, 7, 68);
	std::cout << val << '\n';
}
Last edited on
Thank you for your reply. I think we can't change the signature of non-template only minD with three parameters
Last edited on
In that case, I have no idea, because you can't implicitly convert a const char* into a char* in C++ (you can in C). I guess if you compile as C++03 it might only be a warning? What is your compiler.
Last edited on
So, The only solution is casting right?
This is incredibly ugly. Please somebody save me from myself.

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <cstring> // strcmp
#include <iostream> // printing for test

template <typename T>
const T &minD(T const& a, T const& b)
{
    std::cout << "minD(T const&)\n";
	if (a > b)
	{
		return b;
	}
	else
	{
		return a;
	}
}

char *minD(char * a, char * b)
{
    std::cout << "minD(char*)\n";
	if (strcmp(a, b) > 0)
	{
		return b;
	}
	else
	{
		return a;
	}
}

template <typename T>
const T &minD(T const &a, T const &b, T const &c)
{
	return minD(minD(a, b), c);
}

template <typename T>
const T *minD(T const *a, T const *b, T const *c)
{
	return minD(minD(const_cast<T*>(a), const_cast<T*>(b) ), const_cast<T*>(c));
}

int main()
{
	int val = minD(42, 7, 68);
	
	const char *  const s0 = "CSC";
	const char *  const s1 = "461";
	const char *  const s2 = "This is test";
	
	const char *s = minD(s0, s1, s2);
	
	std::cout << val << '\n';
	std::cout << s << '\n';
}

minD(T const&)
minD(T const&)
minD(char*)
minD(char*)
7
461


...At this point, it would make more sense to just have the last template not be a template, but a three-arg char* function.
Last edited on
Thank you so much for your time. I appreciate it.
Topic archived. No new replies allowed.