How to call generic template function in a specialization version - c++

Have a problem about how to call the generic template version in a specialization version.
Here is the sample code. But the "vector::push_back(a)" calls itself recursively.
#include <iostream>
#include <vector>
using namespace std;
namespace std
{
template<>
void vector<int>::push_back(const int &a)
{
cout << "in push_back: " << a << endl;
vector::push_back(a); // Want to call generic version
}
}
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(1);
return 0;
}

When you create specialization for some template (no difference class of function), you tell to compiler to generate that one instead of general. So in fact if you have specialization you have no general version for that specialization and you can't call it, because it doesn't exists.

You can simply extract the code into another template function:
template<typename T>
void baseF(T t) { ... }
template<typename T>
void F(T t) { baseF<T>(t); }
template<>
void F<int>(int t) { baseF<int>(t); }

Well, to complement, I think it works for template function specification in some situations.
#include <iostream>
#include <vector>
using namespace std;
class Base
{
public:
virtual int test() {return 0;}
};
class Derived : public Base
{
public:
virtual int test() {return 1;}
};
template<class T>
void TestOutput(T* a)
{
cout << a->test() << endl;
}
template<>
void TestOutput(Derived* a)
{
cout << "something else" << endl;
TestOutput<Base>(a);
}
int main()
{
Derived d;
TestOutput(&d);
}
I compiled it with visual studio 2013 and the output is:
something else
1
Although I don't think you can always find a TestOutput function of Base to call the generic one.

Related

C++ non-generic class in template

I would like to know how to make a template with an own class:
#include <iostream>
using namespace std;
template<C cc> void A()
{
cout << cc.l << endl;
}
int main()
{
C cc;
A<cc>();
}
class C
{
public:
int l = 10;
};
But it doesn't work, so how to use that class, like a non-generic class parameter, like here:
#include <iostream>
using namespace std;
template<int i> void A()
{
cout << i << endl;
}
int main()
{
A<100>();
}
You can do it as shown below with C++20(&onwards):
//moved definition of C before defining function template `A`
struct C
{
int l = 10;
};
template<C cc> void A()
{
cout << cc.l << endl;
}
int main()
{
//--vvvvvvvvv--------->constexpr added here
constexpr C cc;
A<cc>();
}
Working demo
Two changes have been made:
As template arguments must be compile time constant, constexpr is used.
The definition of C is moved before the definition of function template.

Make int overload a preferable one

Consider following code snippet:
class Foo {
public:
void bar(std::size_t){}
void bar(const char* ){}
};
int main() {
auto foo = Foo{};
foo.bar(0);
}
It produces ambiguous calls errors (check here). But I think from programmer's perspective it is pretty obvious that I want to call overload with std::size_t. My question is if anything can be done so this code does not produce errors and calls size_t overload?
can be done like this in C++ 20
#include <cstdint>
#include <iostream>
#include <type_traits>
class Foo {
public:
template <typename T>
requires std::is_integral_v<T>
void bar(T){
std::cout<<"hello size_T";
}
void bar(const char* ){
std::cout<<"hello";
}
};
int main() {
auto foo = Foo{};
foo.bar(25);
}
In modern c++ (at least c++17), we prefer to pass string_view as argument over const char* for the none owner transfer cases, so a considerable choice:
#include <cctype>
#include <string>
class Foo {
public:
void bar(std::size_t){}
void bar(std::string_view){}
};
int main() {
auto foo = Foo{};
foo.bar(0);
}
Online demo
In below C++ 20, this works well.
#include <iostream>
class Foo {
public:
template <typename T>
void bar(T) {
std::cout << "hello T" << std::endl;
}
void bar(const char* c) {
std::cout << c << std::endl;
}
};
int main() {
auto foo = Foo{};
foo.bar(0);
foo.bar("test.");
}
This works in C++23:
foo.bar(0zu);
and this works pre-C++23:
foo.bar(size_t{0});

Function specializations in a class Template c++03/c++11 performance

I have two template classes and normally I would prefer the foo version of the Search class. But sadly my compiler can not understand the foo version because of the missing c++11 support. (He will not understand this line: template <typename U = _Format>)
The bar version will create an instance of the _Format type to call the right delegate. So also a constructor is called! Would this be a performance issue compared to the Foo version? (I know this would be this is like premature optimization, but I'm interested)
#include <iostream>
struct format1 {
format1(void) { }
};
struct format2 {
format2(void) { }
};
namespace foo
{
template <typename _Format>
class Search
{
public:
void createData()
{
doCreateData();
}
private:
template <typename U = _Format>
void doCreateData();
template <>
void doCreateData<format1>()
{
using namespace std;
cout << "Format1" << endl;
}
template <>
void doCreateData<format2>()
{
using namespace std;
cout << "Format2" << endl;
}
};
}
namespace bar
{
template <typename _Format>
class Search
{
public:
void createData(void)
{
doCreateData(_Format());
}
private:
void doCreateData(format1)
{
using namespace std;
cout << "Format1" << endl;
}
void doCreateData(format2)
{
using namespace std;
cout << "Format2" << endl;
}
};
}
int main(int argc, char *argv[])
{
(void)argc; (void)argv;
bar::Search<format2> search;
search.createData();
}

How to choose among similar functions from different namespaces based on template parameter

the title and the code is self-explanatory,
Is such a thing possible?how?
Is it encouraged? if not, what is the alternative?
thanks
#include <iostream>
using namespace std;
namespace A
{
void foo()
{
cout << "In A\n";
}
}
namespace B
{
void foo()
{
cout << "In B\n";
}
}
template <typename X>
struct Foo {
void foo()
{
X::foo();
}
};
int main()
{
Foo<A> _foo;
_foo.foo();
return 0;
}
You cannot use a namespace as a template type (namespaces are not types); your code does not compile. The best you can hope for is to use Argument Dependent Lookup (ADL), but it won't work for functions taking no parameters.
If you rename your member function, you can find it via ADL by using a proxy tag:
namespace A
{
struct tag {};
void foo(tag)
{
std::cout << "In A\n";
}
}
namespace B
{
struct tag {};
void foo(tag)
{
std::cout << "In B\n";
}
}
template<class Tag>
struct Foo {
void fooADL()
{
foo(Tag{});
}
};
int main()
{
Foo<A::tag> f;
f.fooADL();
}
Is such a thing possible?
No, you can't parametrise a namespace.
if not, what is the alternative?
Use classes, rather than namespaces, to provide parametrisable scopes for the functions:
struct A {
static void foo();
};
struct B {
static void foo();
}

How to have a c++ object with a method that takes argument the enclosing class?

I am trying to figure out if there's any known pattern/idiom in c++ for what I am trying to do here. Class A must be composed of an object that has a function whose argument must also be of type A. The following code doesn't compile since typeid may not be used in a constant expression. Any suggestions?
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
struct B {
int f(T& i) { cout << "Hello\n"; }
};
class A {
B<typeid(A)> b;
};
int main()
{
A k;
}
Your stated requirements don't need templates at all, just a forward declaration:
#include <iostream>
class A; // forward declare A
struct B {
int f(A &i); // declaration only, definition needs the complete type of A
};
class A {
B b;
};
int B::f(A &i) { std::cout << "Hello\n"; } // define f()
int main()
{
A k;
}
You are looking for B<A> b; The following program compiles without error or warning on g++ 4.4.3.
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
struct B {
int f(T& i) { cout << "Hello\n"; return 0; }
};
class A {
public:
B<A> b;
};
int main()
{
A k;
return k.b.f(k);
}
Note: If you are using templates only to avoid forward declaration, my solution is wrong. But, I'll leave it here in case you are using templates for some other legitimate reason.