Double partial template specialization for a class - c++

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

Related

Derive (virtual) function arguments in variadic template class

I'm building an interpreter and trying to avoid some boilerplate I run into when implementing builtin-functions. I am able to to do this by using templates.
Take this base template for instance:
template<ast::builtin_type T>
class builtin_procedure abstract : public builtin_procedure_symbol
{
using arg_traits = builtin_type_traits<T>;
protected:
builtin_procedure(const symbol_identifier& identifier): builtin_procedure_symbol(identifier)
{
this->register_param(arg_traits::param_id(), T);
}
/**
* The actual implementation of the built-in function
*/
virtual void invoke_impl(typename arg_traits::builtin_type) = 0;
public:
void invoke(scope_context& procedure_scope) override
{
auto raw_arg = procedure_scope.memory->get(procedure_scope.symbols.get(arg_traits::param_id()));
this->invoke_impl(arg_traits::get_from_expression(raw_arg));
}
};
To implement a built-in function function that takes a string, I only need to do:
class builtin_procedure_writeln final : public builtin_procedure<ast::builtin_type::string>
{
protected:
void invoke_impl(arg_traits::builtin_type arg) override;
public:
builtin_procedure_writeln();
}; /* Implementation in cpp file */
Very convenient, I only need to implement the virtual invoke_impl method and that's it.
I'm trying to wrap my head around getting this implemented with a variable number of template arguments so I don't have to duplicate my template definition if I want to support 2, 3, or more arguments in my derived implementation like in the example below.
This would be the template above to support a second template parameter:
template<ast::builtin_type T1, ast::builtin_type T2>
class builtin_procedure abstract : public builtin_procedure_symbol
{
using arg1_traits = builtin_type_traits<T1>;
using arg2_traits = builtin_type_traits<T2>;
protected:
builtin_procedure(const symbol_identifier& identifier): builtin_procedure_symbol(identifier)
{
this->register_param(arg_traits::param_id(1), T1);
this->register_param(arg_traits::param_id(2), T2);
}
/**
* The actual implementation of the built-in function
*/
virtual void invoke_impl(typename arg1_traits::builtin_type, typename arg2_traits::builtin_type) = 0;
public:
void invoke(scope_context& procedure_scope) override
{
auto raw_arg1 = procedure_scope.memory->get(procedure_scope.symbols.get(arg1_traits::param_id()));
auto raw_arg2 = procedure_scope.memory->get(procedure_scope.symbols.get(arg2_traits::param_id()));
this->invoke_impl(arg1_traits::get_from_expression(raw_arg1), arg2_traits::get_from_expression(raw_arg2));
}
};
I know that essentially through template recursion you can essentially iterate through each of the template parameters to do whatever you want to do, but what about the definition of the virtual invoke_impl method? Each of the parameters are derived from the the traits struct, and the call to the method itself also seems not something you could some with template recursion.
How (if) it possible to use a variadic template to allow for a variable number of arguments on this base class as an alternative to just copy/paste this base class with more template arguments?
The final clue was given n314159, this works:
template<ast::builtin_type... Ts>
class builtin_procedure abstract : public builtin_procedure_symbol
{
private:
template<ast::builtin_type T>
typename builtin_type_traits<T>::builtin_type make_arg(scope_context& procedure_scope, int param_id)
{
auto raw_arg = procedure_scope.memory->get(procedure_scope.symbols.get(builtin_type_traits<T>::param_id(param_id++)));
return builtin_type_traits<T>::get_from_expression(raw_arg);
}
protected:
builtin_procedure(const symbol_identifier& identifier, ::symbol_table* runtime_symbol_table): builtin_procedure_symbol(identifier, runtime_symbol_table)
{
auto param_id = 0;
((void) this->register_param(builtin_type_traits<Ts>::param_id(++param_id), Ts), ...);
}
virtual void invoke_impl(typename builtin_type_traits<Ts>::builtin_type...) = 0;
public:
void invoke(scope_context& procedure_scope) override
{
auto param_id = 0;
this->invoke_impl(make_arg<Ts>(procedure_scope, ++param_id)...);
}
};
So, I wrote a small example. I don't think one can do aliasing for variadic templates, so I left that out, but it works without even if it is less nice. So, since I can't use non-integral non-type template parameters, I switched your ast::builtin_type to int, but I think you can reverse that easily enough. The following compiles (but doesn't link, obviously^^).
template<int i>
struct builtin_traits {
static int param_id(int) { return i;}
using builtin_type = int;
};
class builtin_procedure_symbol {
void register_param(int, int);
};
int get(int); // my replacement for procedure_scope.memory->get(procedure_scope.symbols.get
template<int... Ts>
class builtin_procedure : builtin_procedure_symbol{
builtin_procedure(): builtin_procedure_symbol()
{
((void) this->register_param(builtin_traits<Ts>::param_id(1), Ts), ... );
}
virtual void invoke_impl(typename builtin_traits<Ts>::builtin_type...) = 0;
void invoke()
{
auto f = [&](const auto& arg) {
auto raw_arg = get(builtin_traits<arg>::param_id());
return builtin_traits<arg>::get_from_expression(raw_arg);
};
this->invoke_impl(f(Ts)...);
}
};
I hope that helps you. If something is unclear, please ask.

Specifying one of class template argument value as any

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() { ... }

Derived from template class?

I'm trying to use the following code, but can't get it to complete.
Can anyone see the problem?
class IResourceJob
{
public:
virtual ~IResourceJob() {}
virtual void execute() = 0;
};
template<typename T>
class ResourceJob : public IResourceJob
{
public:
void execute()
{
static_assert(false, "Specialised ResourceJob<T> not defined!");
}
};
template<>
class ResourceJob<int>
{
public:
void execute()
{
// test.
}
};
The following usage gives a compile error:
IResourceJob* job = new ResourceJob<int>;
Thanks!
The compiler gives an error for any template that can never be instantiated. For your member function of the class template (i assume you mean static_assert), that is true, so the compiler is in right to give you a diagnostic.
You want to make the condition depend on T and cleverly make it always evaluate to false when instantiated. For example like
template<typename T>
struct always_false : std::false_type {};
template<typename T>
class ResourceJob : public IResourceJob
{
public:
void execute()
{
static_assert(always_false<T>::value,
"Specialised ResourceJob<T> not defined!");
}
};
Since the compiler cannot know whether the user will put a specialization of always_false (which you won't, of course), it cannot early-reject the template anymore.
I also doubt that you wanted to put the static_assert into execute, since your error message indicates that ResourceJob as a whole needs to be specialized. So put the static_assert outside of the member function into the class body. If you don't want the user to specialize the whole template, but only the member function, the user instead needs to say
// either "inline" and in the header, or not "inline" and in the .cpp file, but then
// put this into the header: template<> void ResourceJob<int>::execute();
template<> inline void ResourceJob<int>::execute() {
}
This will provide an alternative definition of execute which will be used by the template if T is int.
IResourceJob* job = new ResourceJob<int>;
fails because the class ResourceJob<int> is not derived from from IResourceJob.
The code should be
template<>
class ResourceJob<int> : public IResourceJob
{
public:
void execute()
{
// test.
}
};
You need to derive the template specialization as well, as in:
template<>
class ResourceJob<int> : public IResourceJob
{ /* ... */ };

Specify a base classes template parameters while instantiating a derived class?

I have no idea if the title makes any sense but I can't find the right words to descibe my "problem" in one line. Anyway, here is my problem. There is an interface for a search:
template <typename InputType, typename ResultType> class Search {
public:
virtual void search (InputType) = 0;
virtual void getResult(ResultType&) = 0;
};
and several derived classes like:
template <typename InputType, typename ResultType>
class XMLSearch : public Search<InputType, ResultType> {
public:
void search (InputType) { ... };
void getResult(ResultType&) { ... };
};
The derived classes shall be used in the source code later on. I would like to hold a simple pointer to a Search without specifying the template parameters, then assign a new XMLSearch and thereby define the template parameters of Search and XMLSearch
Search *s = new XMLSearch<int, int>();
I found a way that works syntactically like what I'm trying to do, but it seems a bit odd to really use it:
template <typename T> class Derived;
class Base {
public:
template <typename T>
bool GetValue(T &value) {
Derived<T> *castedThis=dynamic_cast<Derived<T>* >(this);
if(castedThis)
return castedThis->GetValue(value);
return false;
}
virtual void Dummy() {}
};
template <typename T> class Derived : public Base {
public:
Derived<T>() {
mValue=17;
}
bool GetValue(T &value) {
value=mValue;
return true;
}
T mValue;
};
int main(int argc, char* argv[])
{
Base *v=new Derived<int>;
int i=0;
if(!v->GetValue(i))
std::cout<<"Wrong type int."<<std::endl;
float f=0.0;
if(!v->GetValue(f))
std::cout<<"Wrong type float."<<std::endl;
std::cout<<i<<std::endl<<f;
char c;
std::cin>>c;
return 0;
}
Is there a better way to accomplish this?
Is there a better way to accomplish
this?
Yes, that design is slightly better, since that's using static-dispatching while calling GetValue() (I'm assuming that dynamic_cast is typo, you actually wanted to type static_cast in Base::GetValue()). In that design, Base::GetValue() is not virtual, yet it is able to call Derived::GetValue() using pointer of type Base. This makes it slightly fast.
But even your way is not that bad. All you've to instantiate your class templates like this:
Search<int,int> *s = new XMLSearch<int, int>();
Your Search *s = new XMLSearch<int, int>() is wrong!
You can typedef your templates as follows:
typedef Search<int,int> iisearch;
typedef XMLSearch<int,int> iixmlsearch;
Then use them:
iisearch *s = new iixmlsearch();
This looks better, right?
Small Modification
You can make your class slightly better performance-wise. For that, write your Search class template as follows:
template <typename InputType, typename ResultType> class Search {
public:
void search (InputType input) //it's not virtual anymore!
{
xmlsearch *_this = getXmlSearch();
xmlsearch->search(input);
}
void getResult(ResultType& result) //it's not virtual anymore!
{
xmlsearch *_this = getXmlSearch();
xmlsearch->getResult(result);
}
private:
typedef XMLSearch<InputType, ResultType> xmlsearch;
xmlsearch* getXmlSearch()
{
static xmlsearch *_this= static_cast<xmlsearch* >(this);
return _this;
}
};
Now your base class is not abstract, as it doesn't define virtual functions. This design is slightly faster than your version!

How to code inlineable mutual abstracion in C++?

Example first:
template <class HashingSolution>
struct State : public HashingSolution {
void Update(int idx, int val) {
UpdateHash(idx, val);
}
int GetState(int idx) {
return ...;
}
};
struct DummyHashingSolution {
void UpdateHash(int idx, int val) {}
void RecalcHash() {}
};
struct MyHashingSolution {
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, GetState(idx)); // Problem: no acces to GetState function, can't do recursive application of templates
...
}
};
In this example I can pass MyHashingSolution to State class so State have access to HashingSolution's methods, but HashingSolution can't call GetState. Is it possible to work around this?
This is in the deepest loop. virtual function here drops the performance by more than 25%.
Inlineing is crucial for me.
As jalf suggests in the comments, you probably want to use a variant of the Curiously Recurring Template Pattern (CRTP). That is, make MyHashingSolution a class template parametrised by the derived class:
template <typename D>
struct MyHashingSolution {
typedef D Derived;
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, derived().GetState(idx));
...
}
private:
// Just for convenience
Derived& derived() { return *static_cast<Derived*>(this); }
};
In this case, because you want the derived State class to also be a template, you need to take the slightly unusual step of declaring State as a class template that takes a template template parameter:
template <template <class T> class HashingSolution>
struct State : public HashingSolution<State<HashingSolution> > {
typedef HashingSolution<State<HashingSolution> > Parent;
void Update(int idx, int val) {
Parent::UpdateHash(idx, val); // g++ requires "Parent::"
}
int GetState(int idx) {
return ...;
}
};
The key point is that, provided State inherits from HashingSolution<State<HashingSolution> >, Derived is a derived class of HashingSolution<State<HashingSolution> > so the static_cast<Derived*>(this) downcast in HashingSolution<State>::derived() compiles and works correctly. (If you mess up and derive State from HashingSolution<SomeOtherType> instead and then try something that involves a call to derived(), the compiler will complain as the requirements for static_cast<> are not met.)
Then declare the concrete State class you want to use like so:
typedef State<MyHashingSolution> MyState;
Unfortunately this solution has the side effect that you will need to change DummyHashingSolution (and any other such types) to templates that ignore their one template argument, in order to make them usable as template template arguments.
As a shot in the dark, considering the almost complete lack of information in the question (see comments): would templates be useful? They're often good for compile-time polymorphism.
To get any more potentially useful information, please explain the problem more. Look at the problem comments. Tell us why you know what micro-optimizations need to be made when you're still working on fundamental design. If there's anything non-mainstream about the compilation or execution environments, give us a few details.