Specifying one of class template argument value as any - c++

Consider this class:
template<class T, int select>
class Foo()
{
public:
Foo() {}
~Foo() {}
Param<select> value;
void SomeInitialization();
...
}
Can I partialy specify SomeInitialization() function without explictly mentioning select value in it's template parametes list? For example I would like to merge functions realization into single one:
template<>
void Foo<SomeClass, 0>::SomeInitialization() { ... }
template<>
void Foo<SomeClass, 1>::SomeInitialization() { ... }
template<>
void Foo<SomeClass, 2>::SomeInitialization() { ... }
Into something like this (pseudocode):
template<>
void Foo<SomeClass>::SomeInitialization() { ... }
where select can be any value, since my SomeInitialization() function's code doesn't use it anyway and all functions of the above have identical code, but I have to copy paste it for every select value.
How can I achieve that? Please provide an answer using example Foo class in my post.

If you take a look at this answer, it seems like all you have to do is:
template<int N>
void Foo<SomeClass, N>::SomeInitialization() { ... }

Related

Implicitly pass the "this" OR the "type" of the calling class to a non-member template function

is there a way to implicitly pass the this of the calling class to a template function being called?
i tried the following so far:
template<class P, class T>
void funcA(P& p, T const* t = this){ //<--does not work.
//...some code here...
}
class TypeX { }
class TypeA {
public:
void DoSomething(){
TypeX x;
funcA(x, this); //compiles fine
//funcA(x); //<---my goal: implicitly pass "this" by default.
}
}
void main(){
TypeA objX;
objX.DoSomething();
}
for the type-of-"this" problem, i had the following working so far:
template<class T, class P>
constexpr auto funcA(P& p) {
//...some code here that also uses type T...
}
class TypeA {
public:
void DoSomething(){
TypeX x;
funcA<TypeA>(x); //<---explicitly passing TypeA. (compiles)
//funcA(x); //<---my goal.
//funcA<>(x); //<---my goal(fair enough)
}
}
}
as you can see, i explicitly pass the TypeA to funcA. looks like redundant to me. though it's currently running fine in my project, i tried making it cleaner by making funcA<TypeA>(x) to funcA(x). but no success so far. i'm hoping it's still possible to do this so i asked here in SO.
In a comment, you said,
funcA must be a non-member of a class, specially the target class it will be called.
Given that, it's not possible to use this as the default value of an argument of the function.
I don't see any problem with the following:
template<class P, class T>
void funcA(P& p, T const* t){
//...some code here...
}
class TypeX { };
class TypeA {
public:
void DoSomething(){
TypeX x;
funcA(x, this); // Explicitly pass "this".
}
};
It is not onerous either.

Is there a way to call varying function of member object based on template variable

I have the following code:
class Person {
void func1() {
obj_.function1();
}
void func2() {
obj_.function2();
}
void func3() {
obj_.function3();
}
Object obj_;
};
It's pretty obvious there is a pattern here...
I would like to know if I can call different functions based on template argument.
the functions inside Object are regular member functions.
Is there any way to do something like the following?
class Person {
template <typename Func>
void generic() {
obj_.Func();
}
Object obj_;
};
Another question: Is there a type for function?
I believe it's the key point for it's doable or not.
Thanks
template <auto Func>
void generic() {
(obj_.*Func)();
}
Then foo.generic<&Object::function1>() calls function1.
Prior to c++17:
template <void (Object::*Func)()>
void generic() {
(obj_.*Func)();
}
should work.

Declare new function inside a class using a template

I'm still learning about templates. I'm not sure whether you can declare/(automatically define) a function inside a class (method) using a template. That is, I have a function template defined like this, for example:
template<typename T>
T getT() {
T result;
return result;
}
And a class, where I want the "new function" to be created, based on the template, like this:
class World{
public:
World();
~World();
getT<int>; //"Magically" create new function from the template (return type 'int')
}
What I actually want is to have only a method with the specific given type in World. That means when I want to "magically" create a method based on the template, I want to sort of copy-paste the template function into the class but with the given type.
For example:
class World{
public:
World();
~World();
//The magically created function with T equal to int
int getT(){
int result;
return result;
}
}
Then of course I expect to be able to call the function:
int main(){
World world; //Create world object
world.getT<int>; //Call the function
return 0;
}
Even though here I say I would call it with getT<int>, it could be only getT() (if it is a perfect copy-paste of the template function).
Be carfull
template<typename T>
T& getT() {
T result;
return result;
}
Will return a reference to a temporary. Please do
template<typename T>
T getT() {
T result;
return result;
}
without "&"
And if it's just for get a specific member, you can use std::tuple.
https://en.cppreference.com/w/cpp/utility/tuple/get
getT<int>; //"Magically" create new function from the template (return type 'int')
I don't think that will work.
It appears as though you would like to be able to use templates like macro expansion. Unfortunately, they are very different things and templates don't work like macro expansion.
However, you can use something like the following:
template<typename T>
struct GetHelper
{
T get()
{
return T{};
}
};
class World : private GetHelper<int>,
private GetHelper<double>
{
public:
World() {}
~World() {}
template <typename T>
get()
{
return static_cast<GetHelper<T>*>(this)->get();
}
};
Now you can use:
World w;
int a = w.get<int>();
double b = w.get<double>();
You may also hide GetHelper as a private type of World as:
class World
{
private:
template<typename T>
struct GetHelper
{
T get()
{
return T{};
}
};
struct Data : GetHelper<int>,
GetHelper<double>{};
Data data;
public:
World() {}
~World() {}
template <typename T>
get()
{
return static_cast<GetHelper<T>*>(&data)->get();
}
};

Double partial template specialization for a class

I've stumbled upon a little problem with a little code I'm doing while learning c++11/14. Basically I have a Debugging class which I want to handle all the message printing. Most debugging/logging classes have log levels of sorts, but I want to use a flag for each message I have.
For that I have a little enum where I define my flags and their values:
enum DebugFlag {
Flag1 = 0,
Flag2 = 1,
Flag3 = 2
};
Aditionally, I have a Debugging class, which I've managed to specialize for Flag types and it works pretty well.
template<DebugFlag T>
class Debug {
public:
template <typename U>
static void print(U &&arg) {}
};
template <>
class Debug<static_cast<DebugFlag>(1)> {
public:
static void print(std::string &&message) {
std::cerr<<message<<"\n";
}
static void print(std::ostream &message) {
std::cerr<<DebugStream()().str()<<"\n";
DebugStream()().str("");
DebugStream()().clear();
}
static void print(std::string &message) {
std::cerr<<message<<"\n";
}
};
To call this class, I use a call like:
Debug<Flag1>::print("Message\n"); // should not do anything with Flag1 compiled to 0 value
Debug<Flag2>::print("Message\n"); // should work
Now I wanted to expand this class to also take bool values, so calls like this will work:
Debug< Flag2<2 >::print("Message\n"); // should not do anything with Flag1 compiled to 2 value
Debug< Flag2<1 >::print("Message\n"); // should work
The problem is I need a second partial specialization for my Debug class, that is bool, and I can't figure exactly what the syntax is for this.
This is the closest I've come to it, but still can't figure out what I'm doing wrong or if it's possible without making a secondary class and changing the way I want my call to look like: http://cpp.sh/6yemn
I don't understand exactly how you want to be able to use your class, but here's something that works.
template <typename T, T v = T()>
class Debug {};
template <>
class Debug<Flag, Flag2> {
public:
void f() { std::cout<<"This is good\n"; }
};
template <>
class Debug<bool, true> {
public:
void f() { std::cout<<"This is good too\n"; }
};
The problem is that you need to specify the type : whether you want to use a bool or a Flag, and then the value. You can instantiate the class like so :
Debug<bool, true> trueDebug;
Debug<Flag, Flag2> flag2Debug;
Other instances won't have the f function unless you add a specialization. For example :
template <Flag v>
class Debug<Flag, v> {
public:
void f() { std::cout<<"This is bad\n"; }
};
Live example

C++ member function applied to object

I want to call member function by passing it as template parameter, without using boost is possible. Here is an example off what I tried to do,
class object { void method(); }
{
object object_instance;
...
apply<object:: method>();
...
template<class F>
void apply() { F(object_instance); } // want to call object_instance.F()
}
that does not work, so question is how do I go about binding object method to an object.
Thanks
above is an example, not the real code. I have a bunch of functions differing only in name, but with many parameters, that I want to wrap around in operators.
Something like:
struct foo
{
void bar(void) {}
};
template <typename R, typename C>
R apply(C& pObject, R (C::*pFunc)())
{
return (pObject.*pFunc)();
}
int main(void)
{
foo f;
apply(f, &foo::bar);
}
this.
This is similar to your code, and will allow passing a member function as a template parameter:
class object { public: void method() {} };
object object_instance;
template<void (object::*F)()>
void apply() {
(object_instance.*F)();
}
int main() {
apply<&object::method>();
return 0;
}
As a member function isn't a type or integral value, you can't pass it as a template parameter. You could do what you seem to want by creating a struct which calls the member function, though having object_instance in scope in the template is rather smelly.
What are you actually trying to do?
This example is for rvalue references in c++ox. Does not work on all compilers.
class Sample
{
public:
void fun() { cout << "Sample::fun\n"; }
};
template<typename Function>
void FunCall( Function&& f)
{
f();
}
void RvaluesDemo()
{
FunCall([&]
{
Sample().fun();
});
}