C++ non-generic class in template - c++

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.

Related

C++: Is there a simple way of using a namespace as template? [duplicate]

This question already has answers here:
Alternative to using namespace as template parameter
(2 answers)
Closed 4 months ago.
Is there a way to use a namespace as a template?
I need to call the same function but from a different namespaces.
Something like that:
There are two namespaces here myNamespace1, myNamespace2 that contain a function with the same name - func()
#include <iostream>
using namespace std;
namespace myNamespace1 {
void func()
{
std::cout<<"myNamespace1" << std::endl;
}
}
namespace myNamespace2 {
void func()
{
std::cout<<"myNamespace2" << std::endl;
}
}
template<auto T>
class A {
public:
void func()
{
T::func();
}
};
}
int main() {
using namespace myNamespace1;
using namespace myNamespace2;
A<myNamespace1> a1;
a1.func(); // output: myNamespace1
A<myNamespace2> a2;
a2.func(); // output: myNamespace2
return 0;
}
A namespace may not be used as a template parameter. But you can use for example a non-type template parameter that denotes a function like for example
#include <iostream>
namespace myNamespace1 {
void func()
{
std::cout << "myNamespace1" << std::endl;
}
}
namespace myNamespace2 {
void func()
{
std::cout << "myNamespace2" << std::endl;
}
}
template<void ( &Func )()>
class A {
public:
void func()
{
Func();
}
};
int main()
{
A<myNamespace1::func> a1;
a1.func();
A<myNamespace2::func> a2;
a2.func();
}
The program output is
myNamespace1
myNamespace2
You can create tag classes:
class myNamespace1Tag {};
class myNamespace2Tag {};
template<typename T>
using A_in = std::conditional_t<std::is_same_v<T, myNamespace1Tag>, myNamespace1::A, std::conditional_t<std::is_same_v<T, myNamespace2Tag>, myNamespace2::A, void>;
A_in<myNamespace1Tag> a1;

How to call member functions from a class nested within a namespace?

I want to call a class member function that's nested within a namespace from a different file, but I don't know how.
For example:
How to call a class member function someFunc() that's located in code.h and nested within namespace "program" from main.cpp.
//code.h
#include <iostream>
namespace program
class test {
private:
int x;
public:
test()
{
test::x = 10;
};
someFunc()
{
cout << x << " ";
};
};
There are some problems in your code
#include <iostream>
namespace program { // <-- braces missing
class test
{
private:
int x;
public:
test()
{
test::x = 10; // <-- test:: is unnecessary but no error
};
void someFunc() // <-- return type missing
{
std::cout << x << " "; // <-- namespace std missing
};
};
} // <-- braces missing
int main() {
program::test t;
t.someFunc();
}

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 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.

How to call generic template function in a specialization version

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.