Iterate a template argument list? - c++

I am trying to figure a way to loop through a template argument list but without success
I cannot use c++11 variadic template feature and it need it to be done at compile time
I can assume there will be no positive argument after a negative one
any idea ?
template< int F1, int F2 ,int F3>
struct TemplatedClass
{
TemplatedClass();
update()
{
/*
for each positive template argument
call a method
*/
}
};

Instead of writing a series of if statements you can also put all the arguments into an array and iterate through it. This way compiler won't be able to optimize your code (you didn't specify if this is required), but it will look much cleaner I think. E.g.
template<int F1, int F2 ,int F3>
struct TemplatedClass
{
TemplatedClass();
update()
{
const int array[] = {F1, F2, F3};
// replace this with std::for_each(...) with functors you need
for (int i = 0; i < sizeof(array)/sizeof(array[0]); ++i)
{
myfunc(array[i]);
}
}
}

Since you will have a finite number of template arguments, you can use a series of if statements.
template<int F1, int F2 ,int F3>
struct TemplatedClass
{
TemplatedClass();
update()
{
if (F1 > 0) myfunc();
if (F2 > 0) myfunc();
if (F3 > 0) myfunc();
// etc.*
}
}

With the number of template arguments fixed, a simple code like this will do:
update()
{
if (F1 > 0) callAMethod();
if (F2 > 0) callAMethod();
if (F3 > 0) callAMethod();
}
The expressions in the if statement are compile-time constants, so the optimizer will optimize it into the code that is equivalent to either calling the method "unguarded" (without a branch) or not calling the method at all. In other words, the decision to call the method or not will be made at compile time by the optimizer for no run-time cost.

Or use helper template if you are not sure the optimizer will get rid of the ifs:
void functionToCall(int number) { /* ... */ }
template<bool doCall>
struct FuncCaller {
template<typename Callable>
FuncCaller(Callable func, int number) { func(number); }
};
template<>
struct FuncCaller<false> {
template<typename Callable>
FuncCaller(Callable, int) {}
};
update()
{
FuncCaller<(F1 > 0)>(functionToCall, F1);
FuncCaller<(F2 > 0)>(functionToCall, F2);
FuncCaller<(F3 > 0)>(functionToCall, F3);
}

you could try doing that using Boost Metaprogramming libraries, but requires you to change the template definition of the class to make room for Boost MPL parameters.
An example of what you want to do with Boost::MPL would be:
#include <boost/mpl/vector.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/pop_back.hpp>
#include <boost/mpl/if.hpp>
#include <iostream>
using namespace boost::mpl;
template<class T>
class Test {
public:
void funcToCall() {
std::cout << "I'm called\n";
}
void update();
};
template<class Y, class T>
struct Update {
static void update(T* t) {
typedef typename pop_back<Y>::type vec_less;
if (back<Y>::type::value > 0)
t->funcToCall();
Update<typename if_<empty<vec_less>, void, vec_less >::type, T>::update(t);
}
};
template<class T>
struct Update<void ,T> {
static void update(T* t) {}
};
template<class T>
void Test<T>::update() {
Update<T, Test<T> >::update(this);
}
int main() {
Test<vector<int_<0>,int_<4>, int_<9> > > t;
t.update();
return 0;
}
The class "Test" would be your original "TemplatedClass". Now instead of getting a list of int template parameters you just get one parameter that is a boost::mpl::vector. This contains all the ints you want to pass and then you call the update function that will call recursively the update methods from struct "Update" that will have the duty of calling the "funcToCall()" method if the int is more than 0.
The output of the program I pasted above is:
MacBook-Pro-di-Marcello:~ Kariddi$ ./test
I'm called
I'm called
Of course you need the Boost libs for this example to work.
You can find information about MPL here:
http://www.boost.org/libs/mpl/doc/index.html
Cheers,
Marcello

Related

Is this "Tag Dispatching"?

Say I have some code:
void barA() { }
void barB() { }
void fooA() {
// Duplicate code...
barA();
// More duplicate code...
}
void fooB() {
// Duplicate code...
barB();
// More duplicate code...
}
int main() {
fooA();
fooB();
}
And I want to remove the duplicate code between fooA and fooB I could use a number of dynamic techniques such as passing in a bool parameter, passing a function pointer or virtual methods but if I wanted a compile time technique I could do something like this:
struct A { };
struct B { };
template<typename Tag> void bar();
template<> void bar<A>() { }
template<> void bar<B>() { }
template<typename Tag> void foo() {
// Duplicate code
bar<Tag>();
// More duplicate code
}
int main() {
foo<A>();
foo<B>();
}
where I have introduced two empty "Tag" classes to indicate which bar to use and templated foo and bar based on the tag class. This seems to do the trick. Questions:
Does this technique have a name? is this an example of "Tag dispatching"? From what I read about Tag dispatching it is slightly different and involves function overloading with a tag parameter. A tag that may have come from a typedef in a trait class.
Is there a more idomatic compile-time technique of achieving the same thing?
Edit:
Another possibility would be to use function overloading of bar instead of template specialization and pass the tag class as a parameter:
struct A { };
struct B { };
void bar(A) { }
void bar(B) { }
template<typename Tag> void foo() {
// Duplicate code
bar(Tag());
// More duplicate code
}
int main() {
foo<A>();
foo<B>();
}
This isn't tag dispatching. As you rightly said in your question, that'd be if you used some compile time trait of A and B to distinguish between the two, and then use that to select between two different overloads.
An good example of tag dispatch would be how std::advance is typically implemented. The function's signature is
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
it can be advanced n positions in a single operation if it meets the requirements of RandomAccessIterator. For lesser iterators we must advance it in a loop. So an implementation would probably do something similar to the following:
namespace detail
{
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::random_access_iterator_tag)
{
it += n;
}
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::bidirectional_iterator_tag)
{
if(n < 0) {
while(n++) --it;
} else {
while(n--) ++it;
}
}
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::input_iterator_tag)
{
assert(n >= 0);
while(n--) ++it;
}
}
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n )
{
detail::advance(it, n,
typename std::iterator_traits<InputIt>::iterator_category());
}
I don't know of any specific name for what you're doing. It's just an example of how one would follow the DRY principle.
If bar took an instance of A and B as an argument, then I'd implement this differently. Instead of making bar a function template, and then providing specializations, I'd let overload resolution do the job for me.
void bar(A const&) { ... }
void bar(B const&) { ... }
But since that's not the case, providing explicit specializations seems the right way to do this.

C++ metaprogramming issue/challenge to generate a type based on it function calls

I have a C++ problem. I want to generate a type based on the type arguments passed to a templated function of it.
Let me illustrate it.
class A {
template<class B> M() { }
void Z() {
// NOTE: Here I want to call to X on each type that was feed it to M.
X<N1>();
X<N1>();
...
X<NN>();
}
template<class B> X() { }
};
For example
A a;
a.M<int>();
a.M<double>();
then a.Z() executes ...
X<int>();
X<double>();
Another example to take into account unique types
A a;
a.M<int>();
a.M<int>();
a.M<double>();
a.M<double>();
then a.Z() will still executes ...
X<int>();
X<double>();
Note that I am generating the type A based on the calls to M.
OK! I think that for that class A that's conceptually impossible because A is not templated type and then it can not vary in that way, In fact that's not possible for any type in C++ (I think). But I want you to get the idea.
I am looking forward for a way to confront this problem using meta-programming, but any advice or solution or reference is welcome.
No metaprogramming needed.
class A {
using XPtr = void (A::*)();
std::vector<XPtr> x_calls;
std::set<std::type_index> x_types;
template <typename B> void X() { ... }
public:
template <typename B> void M() {
bool is_new = x_types.insert(std::type_index(typeid(B))).second;
if (is_new)
x_calls.push_back(&A::X<B>);
...
}
void Z() {
for (auto&& ptr : x_calls) {
(this->*ptr)();
}
}
};
First off, I think you're interface isn't really MPL. To be MPL you'd call it more like typedef MyType mpl::vector<int, double> and then find a way to build a type that called X<...> for each type. However...
#include <iostream>
#include <typeinfo>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template< typename T>
void X() {
cout<<typeid(T).name()<<endl;
}
struct A {
vector< function<void(void)> > callbacks;
void z() {
for( auto a : callbacks ) a();
}
template<typename T>
void M() {
callbacks.push_back( [](){ X<T>();} );
}
};
int main() {
A a;
a.M<int>();
a.M<double>();
a.z();
return 0;
}
does what you want.
$ g++ --std=c++11 && ./a.out
i
d
Ss
See it live
You can achieve similar functionality using boost::fusion::set and boost::mpl.
class A {
struct functoid {
template<typename T>
void operator(T t)
{
/* do something */
}
}
template<class B> M() {
boost::mpl::for_each<B>(functoid());
}
}
A a;
a.template M<boost::fusion::set<int, double, ...>>();
But, in this case, you need to know the actual types, or, register some callback in operator().

C++ template metaprogramming, "static if" workaround - can it be improved?

I have a function that scans the user's file system, fills a vector with the paths, then either sorts it or not. Since the user should be able to decide at compile-time whether he wants the vector sorted or not, I use templates and helper classes in place of a much desired (but not existing) "static if".
Consider this code:
enum class Sort{Alphabetic, Unsorted};
template<Sort TS> struct SortHelper;
template<> struct SortHelper<Sort::Alphabetic>
{
static void sort(vector<string>& mTarget) { sort(begin(mTarget), end(mTarget)); }
};
template<> struct SortHelper<Sort::Unsorted>
{
static void sort(vector<string>&) { }
};
template<Sort TS> struct DoSomethingHelper
{
static void(vector<string>& mTarget)
{
// do something with mTarget
SortHelper<TS>::sort(mTarget);
}
};
The code I've written above is GREATLY simplified from the original, which takes multiple template parameters to allow the user to customize even further the results of the function at compile-time.
Is there an alternative to using all of these helper classes? It gets really messy and hard to read.
Ideally, this is what I would like to write:
enum class Sort{Alphabetic, Unsorted};
template<Sort TS> struct DoSomethingHelper
{
static void(vector<string>& mTarget)
{
// do something with mTarget
static_if(TS == Sort::Unsorted) { /* do nothing */ }
static_if(TS == Sort::Alphabetic) { sort(begin(mTarget), end(mTarget)); }
}
};
Since your value is known at compile time (non-template type parameter) you can perfectly write a "normal" if:
template<Sort TS>
void someFunction(vector<string>& mTarget)
{
if (TS == Sort::Alphabetic) { sort(begin(mTarget), end(mTarget)); }
// else if (TS == Sort::Unsorted) {}
}
The compiler will perform constant folding and dead code elimination (if those optimisations are enabled, of course), and the result will be exactly the same as if you used the hypothetical static_if.
I am afraid there has been a misunderstanding about the usage of static_if.
Certainly you can use static_if (or whatever trick you wish really) to try and get some optimization, but that is not its first goal.
The first goal of static_if is semantical. Let me demonstrate this with std::advance. A typical implementation of std::advance will use a type switch to choose, at compile time, between an O(1) implementation (for Random Access Iterators) and an O(n) implementation (for the others):
template <typename It, typename D>
void advance_impl(It& it, D d, random_access_iterator_tag)
{
it += d;
}
template <typename It, typename D>
void advance_impl(It& it, D d, bidirectional_iterator_tag)
{
if (d > D(0)) { for (D i(0); i < d; ++i) { ++it; } }
else { for (D i(0); i > d; --i) { --it; } }
}
template <typename It, typename D>
void advance_impl(It& it, D d, input_iterator_tag)
{
for (D i(0); i < d; ++i) { ++it; }
}
And finally:
template <typename It, typename D>
void advance(It& it, D d)
{
typename std::iterator_traits<It>::iterator_category c;
advance_impl(it, d, c);
}
Why not use just a if in this case ? Because it would not compile.
a Bidirectional Iterator does not support +=
an Input Iterator (or Forward Iterator) does not support --
Thus, the only way to implement the functionality is to statically dispatch to a function only using the available operations on the given type.
What about template specialization?
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
enum class Sort {
Alphabetic,
Unsorted
};
template<Sort TS> struct DoSomethingHelper {
static void someFunction(vector<string>& mTarget)
{}
};
template<> struct DoSomethingHelper<Sort::Unsorted> {
static void someFunction(vector<string>& mTarget) {
}
};
template<> struct DoSomethingHelper<Sort::Alphabetic> {
static void someFunction(vector<string>& mTarget) {
sort(begin(mTarget), end(mTarget));
}
};
int main() {
vector<string> v = {{"foo", "bar", "foo2", "superman", ".."}};
DoSomethingHelper<Sort::Alphabetic> helper;
helper.someFunction(v);
for (string& s : v) {
cout << s << endl;
}
return 0;
}
Edit: I'm a idiot.

Checking if a function with a given signature exists in c++

So I was looking for ways to check whether a function with a particular argument exists. I have a templated method which relies on an external function (external from the class) to do the job:
template <class Moo>
void exportDataTo(Moo& ret){
extended_solid_loader(ret, *this);
}
At multiple points in the project I have macros which define extended_solid_loader for different types, but now I want to be able to use a default function if extended_solid_loader hasn't been defined for that particular class type.
I came across this:
Is it possible to write a template to check for a function's existence?
but it seems a little different, in that I'm not checking for a method, but rather a definition of a function with a particular argument type.
Is this possible right now?
You can just provide a function template for extended_solid_loader providing a default implementation, and users who want to use something other than the default implementation just specialize that.
template<class T>
void extended_solid_loader(T & ret, SomeClass & obj) {
// default implementation here
}
template<>
void extended_solid_loader<MooClass>(MooClass & ret, SomeClass & obj) {
// special implementation for MooClass here
}
You don't actually have to do anything particularly special. Just make sure there's a version of that function available to the template and let ADL do the dirty work. Check out this example:
#include <iostream>
namespace bob {
struct X {};
void f(X const&) { std::cout << "bob::f\n"; }
}
namespace ed {
template < typename T >
void f(T const&) { std::cout << "ed::f\n"; }
template < typename T >
struct test
{
void doit() // not called f and no other member so named.
{ f(T()); }
};
}
int main()
{
ed::test<int> test1;
ed::test<bob::X> test2;
test1.doit();
test2.doit();
std::cin.get();
}
Works without the namespace stuff too (non-templates have preference). I just used that to show that ADL will pick it up when you do.
Your original question was interesting. Found a way to do it in C++0x:
template < typename T >
struct fun_exists
{
typedef char (&yes) [1];
typedef char (&no) [2];
template < typename U >
static yes check(decltype(f(U()))*);
template < typename U >
static no check(...);
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
};
void f(double const&) {}
struct test {};
#include <iostream>
int main()
{
std::cout << fun_exists<double>::value << std::endl;
std::cout << fun_exists<test>::value << std::endl;
std::cin.get();
}

Function template as a parameter to a class template

<> - read this as a template;
I can do this:
void f() {}
//Here I'm declaring a fnc as a <> param
template<void (*fnc)()>
struct Factor { };
int main()
{
Factor<f> fac;
return 0;
}
but I cannot do this:
#include <sstream>
template<class R, class T>
R make_(T first, T second)
{
std::stringstream interpreter;
R result = R();
interpreter << first << '.' << second;
interpreter >> result;
return result;
}
//Here I'm (trying) to declare fnc <> as a <> param
template<template<class T,class R> R (*fnc)(T,T)>
struct Factor { };
int main(int argc, char* argv[])
{
Factor<make_> fac;
return 0;
}
The BIG Q is: How (if possible) can I declare as a template parameter a fnc template?
Edit
Providing that I've used Armen's advise:
I would like to be able to do something like this (in main):
Factor<f<"1","02">> m;
Then in m I could make a double type out of those args ("1", "02")
There is no syntax for that in C++.
What you should do is instead of function template use functor template, which would fit as a template template parameter.
E.G.
template <class R, class T>
struct f
{
R operator () (T const&)
{
//blah
}
};
template <template<class R, class T> class F >
struct foo
{
///...
};
int main()
{
foo<f> d;
}
Your syntax has some issues. What you do at the end with Factor<make_> fac; is similar to declaring vector<map> v; You need to provide parameters to the template to make it concrete: Factor<make_<int,int> > fac;. But that isn't the whole issue; there are many.
What you're doing with your function isn't quite right. You are providing a specific function (f in the first example), which can be done as a constructor parameter. You should reevaluate your design.
From looking at your make_() function template, it seems that what you actually want is boost::lexical_cast<>(). It does what your make_() does, only better. (For starters, your conversion doesn't check for errors at all.)