Function template as a parameter to a class template - c++

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

Related

C++ templated class with different behaviour depending on type

say you have a class like this:
template <typename T>
class MyClass {
public:
void doSomething();
};
And within a method, is there any way to have different behaviour depending on the type like that:
template <typename T> MyClass::doSomething() {
//this is what I want:
std::string value = "17";
if(T == int) {
int myInt = atoi(value.c_str());
} else if(T == std::string) {
std::string myString = value;
}
}
Is there any easy way to achieve this?
I know I could write a wrapper class that provides a constructor that takes a std::string, so I could use something like:
T myVar(value);
But that would be more resource wasting if using simple type like an int, also I would like to realize that if-else-statement to be able to perform different actions.
I would be thankful for an answer.
regards,
tagelicht
In C++17, you can achieve exactly what you want with if constexpr(...):
template <typename T> MyClass::doSomething() {
//this is what I want:
std::string value = "17";
if constexpr(std::is_same_v<T, int>) {
int myInt = atoi(value.c_str());
} else constexpr(std::is_same_v<T, std::string>) {
std::string myString = value;
}
}
In C++14, you can implement your own static_if quite easily. I gave a tutorial talk about this at CppCon 2016 and Meeting C++ 2016.
template <typename T> MyClass::doSomething() {
//this is what I want:
std::string value = "17";
static_if(std::is_same_v<T, int>)
.then([&](auto) {
int myInt = atoi(value.c_str());
})
.else_if(std::is_same_v<T, std::string>)
.then([&](auto) {
std::string myString = value;
})();
}
In C++11, you probably want to use function overloading or template specialization. Example with the former (updated with suggestions from Jarod42 in the comments):
template <typename> struct tag { };
void call_dispatch(...) { } // lowest priority
void call_dispatch(tag<std::string>)
{
std::string myString = value;
}
void call_dispatch(tag<int>)
{
int myInt = atoi(value.c_str());
}
Usage:
template <typename T> MyClass::doSomething() {
//this is what I want:
std::string value = "17";
call_dispatch(tag<T>{});
}
Two approaches not yet exemplified are 1) tag dispatch and 2) template specialization
Tag dispatch:
Call a helper function that uses overloading
The way we do this is to define some empty templated struct as a lightweight "tag" type:
template <typename T>
class MyClass {
public:
void doSomething();
private:
// tag for dispatch
template<class U>
struct doSomethingTag{};
... and then define helper functions that take specializations of that tag:
void doSomethingHelper(doSomethingTag<std::string>, std::string value);
void doSomethingHelper(doSomethingTag<int>, std::string value);
};
Then we can use the primary entry point (doSomething) as a way to call the specialized helper function:
template <typename T>
void MyClass<T>::doSomething() {
//dispatch to helper function
doSomethingHelper(doSomethingTag<T>{}, "17");
}
Demo
The helper functions look like this:
template <typename T>
void MyClass<T>::doSomethingHelper(doSomethingTag<std::string>, std::string value)
{
int myInt = atoi(value.c_str());
}
template <typename T>
void MyClass<T>::doSomethingHelper(doSomethingTag<int>, std::string value)
{
std::string myString = value;
}
This should incur no overhead for the tag structures because the helper functions don't actually use the tag parameter, so it'll be optimized away. If it's not, it is a 1-byte overhead to construct the struct. (Note: Vittorio Romeo hinted at this in his answer, but he called it "function overloading")
Template specialization
You can "specialize" the template for your function so long as you are fully specializing it (specify the type for the class!):
The syntax for specialization looks a little strange because we keep the angle-brackets empty: <>:
template<>
void MyClass<int>::doSomething() {
//dispatch to helper function
std::string value = "17";
int myInt = atoi(value.c_str());
}
template <>
void MyClass<std::string>::doSomething()
{
std::string value = "17";
std::string myString = value;
}
This enables you to keep a smaller class:
template <typename T>
class MyClass {
public:
void doSomething();
};
Demo 2
Conclusion:
In the specific example you've given, I'd prefer template specialization. However, oftentimes you want to do some kind of partial specialization, and this gets very very strange with member functions, so tag dispatch is often preferred.
With C++17, using constexpr if definitely makes life easier.
How about this:
#include <type_traits>
template <typename T> MyClass::doSomething() {
//this is what I want:
std::string value = "17";
if(std::is_same<T,int>::value) {
int myInt = atoi(value.c_str());
} else if(std::is_same<T,std::string>::value) {
std::string myString = value;
}
}
This is C++11. You can make it even nicer with C++17 with constexpr if. Here there's the problem that you have to cast the values that are not implicitly castable. For example, return of std::string has to be cast to int for this to compile.

Class template specialization that changes only one member function

I have a class template Function that takes a unsigned integer as a template argument, for the number of inputs. This template overloads operator() so the Function can be evaluated for a set of given inputs.
Usually, one of the prototypes for this member would be operator()(double, ...). However, if the template argument is 0, then that prototype wouldn't work, as it requires at least one argument.
template <unsigned Arity>
struct Function {
void operator () (double, ...);
};
Normally, I'd just write a template specialization, but there would be a lot of redundant code since there are a lot of other member functions. Again, normally, I'd make a base class containing the redundant code for the main class definition and the specialization to inherit from.
struct FunctionBase {
// Common code
Function operator + (Function const &) const; // ?
};
template <unsigned Arity>
struct Function : FunctionBase { /* etc */ };
Unfortunately, I'm unsure how to go about doing this, since for example operator+ is meant to return a Function. But how can it do this if Function is only defined later on? Function inherits from the base class, and by this design operator+ is in the base class...
It could return an instance of the base class, but then we need a way to convert that instance to an instance of Function, and I know of no way to do this without copying the first instance's data, which is very expensive in terms of performance.
How can I accomplish this?
The question is quite difficult to answer for it's far from being clear.
Below two possibile alternatives that try to address your issues:
If you want to go ahead with Arity template parameter, you can use sfinae'd operators to deal with Arity equal to 0:
#include<iostream>
template<int Arity>
struct Function {
template<int N = Arity>
std::enable_if_t<N == 0> operator()() {
std::cout << "arity == 0" << std::endl;
}
template<int N = Arity>
std::enable_if_t<N != 0> operator()(double, ...) {
std::cout << "arity != 0" << std::endl;
}
};
int main() {
Function<0> f1;
Function<2> f2;
f1();
f2(0., 42);
}
This way you no longer need to introduce a base class and all the related problems don't apply anymore.
If you mind changing approach instead, you can switch to the following pattern for your function object:
template<typename>
struct Function;
template<typename R, typename... A>
struct Function<R(A...)> {
R operator()(A... args) {
// ...
}
// ...
};
You can use it as it follows:
Function<void(int, char)> f;
If you want to have a fixed double as you first parameter for operator(), you can do this:
template<typename R, typename... A>
struct Function<R(double, A...)> {
R operator()(double d, A... args) {
// ...
}
// ...
};
And use it as it follows:
Function<void(double, int, char)> f1;
Function<void(double)> f1;
This will help at least dealing easily with empty parameter packs (note that sizeof...(A) will return you the number of submitted parameters in any case).
It follows a minimal, working example implementation:
#include<iostream>
template<typename>
struct Function;
template<typename R, typename... A>
struct Function<R(A...)> {
R operator()(A... args) {
int _[] = { 0, (std::cout << args << std::endl, 0)... };
(void)_;
}
template<typename... O>
Function<R(A..., O...)> operator+(Function<R(O...)>) {
return {};
}
// ...
};
int main() {
Function<void(int)> f1;
Function<void(double)> f2;
f1(42);
f2(0.);
(f1+f2)(3, .3);
}

Any way to let the use of function pointers as template arguments easier?

I can use function pointer as template argument as the following
template<class R, class T, R (*Fun)(T)>
class MyClass;
Any way to make it is easy as
MyClass<&MyFun> a;
Here is a horrible answer, but I cannot think of a better one.
template<typename R, typename Arg, R(*Fun)(Arg)>
class MyClass {};
template<typename R, typename Arg>
struct MyClassHelper {
template<R(*Fun)(Arg)>
struct Class {
typedef MyClass<R, Arg, Fun> type;
};
};
template<typename R, typename Arg>
MyClassHelper<R, Arg> GetMyClass(R(*Fun)(Arg)); // no impl
void MyFun(int) {}
int main() {
typedef decltype( GetMyClass(&MyFun) ) A;
typedef A::Class<&MyFun> B;
typedef B::type a;
// or, in one line:
decltype( GetMyClass(&MyFun) )::Class<&MyFun>::type b;
}
which is ugly as sin. But at least it extracts the argument types of MyFun without repeating them...
It's not possible exactly as in the question, but yes it's possible if you flex your design a little bit. Let's take an example:
Suppose you have below function:
int foo (int i) { return i; }
Now you want to write:
MyClass<&foo> a; // instead of `Myclass<int, int, &foo> a;
Here how you will achieve it. First change the simple function:
int foo (int i) { return i; }
to encapsulated function object:
struct foo { // <--- function name here
int operator () (int i) { return i; } // <--- function body here
};
Both are almost same (in the case of function object an extra this pointer is passed which doesn't happen in the free function case):
int x = foo(2); // 1st case
int x = foo_(2); // 2nd case where `foo_` is an object of `struct foo`
Now you can use simply as you want!
template<class Func>
class MyClass {...}
MyClass<foo> a;
Here is a working demo.
There's already std::ptr_fun. With C++11, you can use it as
auto a = std::ptr_fun(&MyFun);
Update:
As the other attempts, and non attempts BTW, have shown, isn't it possible with your kind of template, least of all "as easy as" ;-). What you can do however, is sort of reimplement the existing standard template function pattern (std::ptr_fun, std::make_pair and the like) to return the desired type, if your main goal is "as easy as".

Iterate a template argument list?

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

template argument deduction for pointer to member function?

I am trying to build a statically bound delegate class, where the member function is bound at compile time, thereby aiding optimisation.
I have the following code which works exactly how I want it to:
#include <iostream>
namespace thr {
template<typename T, T func>
struct delegate;
template<typename R,
typename C,
typename... A,
R (C::* mem_fun)(A...)>
struct delegate<R(C::*)(A...), mem_fun>
{
delegate(C* obj_)
: _obj(obj_)
{}
R operator()(A... a)
{
return (_obj->*mem_fun)(a...);
}
private:
C* _obj;
};
} // namespace thr
struct foo
{
double bar(int i, int j)
{
return (double)i / (double)j;
}
};
int main()
{
foo f;
typedef thr::delegate<decltype(&foo::bar), &foo::bar> cb;
cb c(&f);
std::cout << c(4, 3);
return 0;
}
However, the usage is not very elegant:
thr::delegate<decltype(&foo::bar), &foo::bar>
I would like to use a function template which deduces the template parameters and returns a delegate instance; something along the lines of (this code does not compile):
template<typename C, typename T, T func>
thr::delegate<T, func> bind(T func, C* obj)
{
return thr::delegate<decltype(func), func>(obj);
}
This would allow for more elegant syntax:
auto cb = bind(&foo::bar, &f);
Is it possible to deduce a non-type parameter in a function template?
Is what I'm trying to achieve even possible?
Would std::function help? http://www2.research.att.com/~bs/C++0xFAQ.html#std-function Your example looks quite close.
I think the compiler supplied STL does pretty horrible things to make it work smoothly. You may want to have a look at as an example before giving up.
Edit: I went out and tried what you try to accomplish. My conclusion is a compile error:
The return type of the bind (delegate) must name the pointer to member because it is your own requirement.
bind should accept the name of the pointer to member to be elegant (i.e. your requirement)
Compiler requires you to not shadow the template parameter with a function parameter or use the name in both parameters and return type.
Therefore one of your requirements must go.
Edit 2: I took the liberty of changing your delegate so bind works as you wish. bind might not be your priority though.
#include <iostream>
namespace thr {
template<typename C,typename R,typename... A>
struct delegate
{
private:
C* _obj;
R(C::*_f)(A...);
public:
delegate(C* obj_,R(C::*f)(A...))
: _obj(obj_),_f(f)
{}
R operator()(A... a)
{
return (_obj->*_f)(a...);
}
};
} // namespace thr
template<class C,typename R,typename... A> thr::delegate<C,R,A...> bind(R(C::*f)(A...),C* obj){
return thr::delegate<C,R,A...>(obj,f);
}
struct foo
{
double bar(int i, int j)
{
return (double)i / (double)j;
}
};
int main()
{
foo f;
auto c = bind(&foo::bar, &f);
std::cout << c(4, 6);
return 0;
}
It is possible to deduce other entities than types in a function signature, but function parameters themselves cannot then be used as template parameters.
Given:
template <size_t I> struct Integral { static size_t const value = I; };
You can have:
template <size_t N>
Integral<N> foo(char const (&)[N]);
But you cannot have:
Integral<N> bar(size_t N);
In the former case, N as the size of the array is part of the type of the argument, in the latter case, N is the argument itself. It can be noticed that in the former case, N appeared in the template parameters list of the type signature.
Therefore, if indeed what you want is possible, the member pointer value would have to appear as part of the template parameter list of the function signature.
There may be a saving grace using constexpr, which can turn a regular value into a constant fit for template parameters:
constexpr size_t fib(size_t N) { return N <= 1 ? 1 : fib(N-1) + fib(N-2); }
Integral<fib(4)> works;
But I am not savvy enough to go down that road...
I do however have a simple question: why do you think this will speed things up ? Compilers are very good at constant propagation and inlining, to the point of being able to inline calls to virtual functions when they can assess the dynamic type of variables at compilation. Are you sure it's worth sweating over this ?