Templated Functions.. ERROR: template-id does not match any template declaration - c++

I have written a function template and an explicitly specialized templated function which simply takes in 3 arguments and calculates the biggest among them and prints it.
The specialized function is causing an error,whereas the template works fine.
But I want to work with char* type.
This is the error I get=>
error: template-id ‘Max<>’ for ‘void Max(char, char, char)’ does not match any template declaration
Following is my code:
template <typename T>
void Max(T& a,T& b,T& c)
{
if(a > b && a >> c)
{
cout << "Max: " << a << endl;
}
else if(b > c && b > a)
{
cout << "Max: " << b << endl;
}
else
{
cout << "Max: " << c << endl;
}
}
template <>
void Max(char* a,char* b,char* c)
{
if(strcmp(a,b) > 0 )
{
cout << "Max: " << a << endl;
}
else if(strcmp(b,c) > 0)
{
cout << "Max: " << b << endl;
}
else
{
cout << "Max: " << b << endl;
}
}

You need to take the pointers by reference:
template <>
void Max(char*& a,char*& b,char*& c)
That said, it would be better not to use an explicit specialization and instead just overload the function:
void Max(char* a, char* b, char* c)
It's almost always a bad idea to specialize function templates. For more, see Herb Sutter's "Why Not Specialize Function Templates?"

I ran into the same problem and fixed it by using typedef:
typedef char * charPtr;
template <>
void Max(charPtr &a, charPtr &b, charPtr &c)

Related

Templates with const parameters does not dispatch as expected

I'm trying to dispatch my calls in 2 different functions. One for pointers and the other for references. But as soon as I use the const qualifier, templates doesn't dispatch as expected. In my case, the get_pixel doesn't use any const qualifier because it is supposed to edit the given parameter. And set_pixel is supposed to use the given parameter but don't edit it and I would like those parameters to remain const.
#include <iostream>
template <typename Color>
inline int get_pixel(
Color& color)
{
return 1;
}
template <typename T>
inline int get_pixel(
T components[])
{
return 2;
}
template <typename Color>
inline int set_pixel(
const Color& color)
{
return 1;
}
template <typename T>
inline int set_pixel(
const T components[])
{
return 2;
}
template <typename Color>
inline int set_pixel_no_const(
Color& color)
{
return 1;
}
template <typename T>
inline int set_pixel_no_const(
T components[])
{
return 2;
}
int main()
{
float c;
float tab[1];
std::cout << "Get PIXEL\n";
std::cout << "Dispatch for c : " << get_pixel(c) << "\n"; // 1
std::cout << "Dispatch for &c : " << get_pixel(&c) << "\n"; // 2
std::cout << "Dispatch for tab : " << get_pixel(tab) << "\n"; // 2
std::cout << "Set PIXEL\n";
std::cout << "Dispatch for c : " << set_pixel(c) << "\n"; // 1
std::cout << "Dispatch for &c : " << set_pixel(&c) << "\n"; // 1, Should be 2
std::cout << "Dispatch for tab : " << set_pixel(tab) << "\n"; // 1, Should be 2
std::cout << "Set PIXEL NO CONST\n";
std::cout << "Dispatch for c : " << set_pixel_no_const(c) << "\n"; // 1
std::cout << "Dispatch for &c : " << set_pixel_no_const(&c) << "\n"; // 2
std::cout << "Dispatch for tab : " << set_pixel_no_const(tab) << "\n"; // 2
return 0;
}
Any idea why the const qualifier is a problem here ?
The template deduction doesn't work as a text substitution, but on the T as a whole.
When T in const T is deduced as float* you don't get const float*, but float* const.
Or const (float*), if we had such a syntax.
I may be wrong, but i think basically this question boils down to this:
#include <iostream>
template <typename T>
int f(T const &)
{
//std::cout << __PRETTY_FUNCTION__ << "\n";
return 1;
}
template <typename T>
int f(T const *)
{
//std::cout << __PRETTY_FUNCTION__ << "\n";
return 2;
}
int main()
{
float c = 1.f;
float * addr = &c;
float const * addr_const = &c;
f(c); // 1
f(&c); // 1 you expected 2
f(addr); // 1 you expected 2
f(addr_const); // 2 as you expect
return 0;
}
Your const array function parameter is the same as a const pointer parameter in the function declaration(so i put it in this way in the example).
I think the first function is the base template, while the second version is a more specialized version (since it only takes pointers to const T). So the const reference one gets chosen when you pass a pointer to non const. Except in the case you really pass it a pointer to const as argument.
If you use gcc (i think) you can use __PRETTY_FUNCTION__ to display the deduced arguments

Overload resolution, name lookup and function pointers

I have a case where lookup and overload resolution behaves differently:
for user-defined class vs built-in types vs std::string
for direct call vs function pointer call
I cannot figure what exact parts of the standard justify these differences.
Consider the following C++11 code:
#include <iostream>
#include <string>
using namespace std;
struct Test1 {};
struct Test2 {};
template<typename T>
int f(T t) { return 0; }
int f(Test1 t) { return 10; }
int f(int y) { return 20; }
template<typename T>
int use1() { return f(T()); }
template<typename T>
int use2() { auto fp = static_cast<int(*)(T)>(&f); return (*fp)(T()); }
int f(Test2 t) { return 30; }
int f(string s) { return 40; }
int f(double y) { return 50; }
int main() {
cout << "use1<float>: " << use1<float>() << endl;
cout << "use1<Test1>: " << use1<Test1>() << endl;
cout << "use1<int>: " << use1<int>() << endl;
cout << "use1<Test2>: " << use1<Test2>() << endl;
cout << "use1<string>: " << use1<string>() << endl;
cout << "use1<double>: " << use1<double>() << endl;
cout << endl;
cout << "use2<float>: " << use2<float>() << endl;
cout << "use2<Test1>: " << use2<Test1>() << endl;
cout << "use2<int>: " << use2<int>() << endl;
cout << "use2<Test2>: " << use2<Test2>() << endl;
cout << "use2<string>: " << use2<string>() << endl;
cout << "use2<double>: " << use2<double>() << endl;
return 0;
}
Output is (same with g++ 6.3 and clang++5.0.0 trunk):
use1<float>: 0
use1<Test1>: 10
use1<int>: 20
use1<Test2>: 30
use1<string>: 0
use1<double>: 0
use2<float>: 0
use2<Test1>: 10
use2<int>: 20
use2<Test2>: 0
use2<string>: 0
use2<double>: 0
Questions:
Why use1<string> is different from use1<Test2> ? Both types are declared "at the top", both f() overloads are declared at the bottom.
Why use1<Test2> is different from use1<double>? Corresponding f() overloads are on adjacent lines, is there anything special in treatment of built-in types?
Why use1<Test2> is different from use2<Test2>? The type of a pointer to function in use2 seems to match the calling context in use1.
Two-phase name lookup. At the point where use1 is defined, three overloads of f are visible via normal lookup. At the point of instantiation, additional overloads may be found - but only by argument-dependent lookup. Test2 is in global namespace, so f(Test2) is found by ADL; whereas string is in namespace std, and so f(string) (which is, obviously, not in namespace std) is not found by ADL. double has no associated namespaces, and so ADL doesn't kick in at all.
In use2, f is not a dependent name, and so the second-phase lookup is not performed at all - only overloads visible at the point of definition are considered.

std::basic_string template specialization

I'm trying to create my own string class using std::basic_string<> with a custom allocator. It's seems to be mostly working thanks in large part to other related topics on stackoverflow. But I really want this to be a drop in replacement of std::string. To that end, it needs to assignable to/from std:string. I tried overloading assignment operators and such but I can't seem to get that working.
The end goal here is to be able to log/track memory allocations for strings in existing code by replacing std::string. If there's a better way of doing that, I'd like to hear it as well.
This is an embedded application so my options with 3rd party tools is limited.
Here's a sample app with the code I have already.
dave
#include <iostream>
using namespace std;
namespace mw_allocator_namespace
{
int mw_allocator_space =0;
template <typename T>
class mw_allocator: public std::allocator<T>
{
public:
typedef size_t size_type;
typedef T* pointer;
typedef const T* const_pointer;
template<typename _Tp1>
struct rebind
{
typedef mw_allocator<_Tp1> other;
};
pointer allocate(size_type n, const void *hint=0)
{
pointer p = std::allocator<T>::allocate(n, hint);
mw_allocator_space += n*sizeof(T);
cout << hex << " Alloc: " << n << " : " << n*sizeof(T) << " (" << reinterpret_cast<unsigned long long>(p) << ")" << endl;
return p;
}
void deallocate(pointer p, size_type n)
{
cout << hex << " Dealloc: " << n << " : " << n*sizeof(T) << " (" << reinterpret_cast<unsigned long long>(p) << ")" << endl;
mw_allocator_space -= n*sizeof(T);
std::allocator<T>::deallocate(p, n);
}
mw_allocator() throw(): std::allocator<T>() { cout << " Hello allocator!" << endl; }
mw_allocator(const mw_allocator &a) throw(): std::allocator<T>(a) { }
template <class U>
mw_allocator(const mw_allocator<U> &a) throw(): std::allocator<T>(a) { }
~mw_allocator() throw() { }
};
}
typedef std::basic_string<char, std::char_traits<char>, mw_allocator_namespace::mw_allocator<char> > my_string;
int main() {
string s1("Hello World1");
my_string ms1;
#if 0
// This doesn't work
ms1 = s1;
#else
// This does...
ms1 = s1.c_str();
#endif
cout << "ms1: " << ms1 << endl;
return 0;
}

Ambiguous call to overloaded function (learning about templates)

I started learning about templates and I copied the code from my book but the compiler is giving me this error
Error 1 error: 'swap' : ambiguous call to overloaded function"
Here is my program
#include <iostream>
template <typename X>
void swap(X &a, X &b);
int _tmain(){
using namespace std;
int a, b;
cout << "enter two numbers:\n";
cin >> a >> b;
cout << "Your numbers are: " << a << ", " << b << endl;
swap(a, b); //error is here
cout << "Your numbers reversed are: " << a << ", " << b << endl;
return 0;
}
template <typename X>
void swap(X &a, X &b){
X temp = a;
a = b;
b = temp;
}
You are redefining the function swap with the same signature, so you're having an ambiguous definition of it, and, consequently, an ambiguous call.
If you want to maintain the function with the same signature, you should either choose to use not the "using namespace std;", which will not shadow your swap() definition, or simply define tthe function in another namespace.
Example:
namespace your_namespace {
template <typename X>
void swap(X &a, X &b) {
X temp = a;
a = b;
b = temp;
}
}
int foo(10), bar(20);
std::cout << "foo: " << foo << "; bar: " << bar << std::endl;
your_namespace::swap(foo, bar);
std::cout << "foo: " << foo << "; bar: " << bar << std::endl;
Output:
foo: 10; bar: 20
foo: 20; bar: 10
Regards!

Template class expression parameter overloading

Hey, I'm trying to figure out if it's possible to "overload" a template class deffinition with expression parameters. Kind of like the following snippet of code.
template<class T>
class Test
{
public:
T testvar;
Test()
{
testvar = 5;
cout << "Testvar: " << testvar << endl;
}
};
template<class T>
class Test<T, int num>
{
public:
T testvar;
Test()
{
testvar = 10;
cout << "Testvar: " << testvar << endl;
cout << "Param: " << num << endl;
}
};
Thanks.
Edit: For the record, i'm trying to do this with C++ if that wasn't obvious... :)
Templates allow default template parameters, which can provide something similar to what you're looking for..
template<class T, int num = -1>
class Test
{
public:
T testvar;
Test()
{
testvar = (num == -1 ? 10 : 5);
cout << "Testvar: " << testvar << endl;
if ( num != -1 )
cout << "Param: " << num << endl;
}
};
If you want to be able to specify just one template argument for Test, you will need to declare a default template parameter as Shmoopty suggests.
It's also possible to partially specialise for different parameter values:
// This base template will be used whenever the second parameter is
// supplied and is not -1.
template<class T, int num = -1>
class Test
{
public:
T testvar;
Test()
{
testvar = 10;
cout << "Testvar: " << testvar << endl;
cout << "Param: " << num << endl;
}
};
// This partial specialisation will be chosen
// when the second parameter is omitted (or is supplied as -1).
template<class T, int num>
class Test<T, -1>
{
public:
T testvar;
Test()
{
testvar = 5;
cout << "Testvar: " << testvar << endl;
}
};
This avoids the need for if or switch statements, which makes it marginally faster (no runtime testing is performed) and allows additional cases to be "grafted on" later in the form of additional partial specialisations. (Although which approach is clearer is a matter of personal taste.)