Is this the only way to evaluate a parameter pack without using folding (since it requires the use of operators)?
#include <iostream>
template<int ...Is, typename Function>
void eval(Function&& f)
{
// (f(Is)...);
auto op = [&f](int i){f(i); return 0;};
auto doNothing = [](auto...){};
doNothing(op(Is)...);
}
int main()
{
eval<0,1,2>([](int x){std::cout << x << "\n";});
}
Essentially I want to do (f(Is)...), but for some reason, this is disallowed in C++. Is there a more elegant way this can be achieved than by using the workaround presented above?
There is a simpler solution:
#include <iostream>
template<int ...Is, typename Function>
void eval(Function&& f)
{
(f(Is),...);
}
int main()
{
eval<0,1,2>([](int x){std::cout << x << "\n";});
}
Related
I have a function with two template arguments, one for a vector data type (int, float, double, etc.) and one for an integer type (int, int16_t, uint32_t, etc.):
template <typename T, typename I>
void
add(std::vector<T> array, std::vector<I> idx) {
// ...
}
For tests, I would now like to loop over every possible combination of data/integer types, e.g.,
// pseudo code
for I in [int, int16_t, int32_t, ...] {
for T in [float, double, int, int16_t, ...] {
// create arguments a, b
add<T, I>(a, b);
}
}
Is it possible to loop over types at all? How?
There may be simpler ways to do this, but I would use the boost hana library, as follows:
#include <boost/hana/for_each.hpp>
#include <boost/hana/tuple.hpp>
#include <vector>
#include <iostream>
#include <boost/type_index.hpp>
namespace hana = boost::hana;
// for example's sake, just print the type
template <typename T, typename I>
void add(std::vector<T> array, std::vector<I> idx) {
using namespace boost::typeindex;
std::cout << type_id<T>().pretty_name() << " - " << type_id<I>().pretty_name() << std::endl;
}
int main() {
auto types1 = hana::tuple_t<int, int16_t, int32_t>;
auto types2 = hana::tuple_t<float, double, int, int16_t>;
hana::for_each(types1, [types2](auto t1) {
hana::for_each(types2, [t1](auto t2) {
using t1_type = typename decltype(t1)::type;
using t2_type = typename decltype(t2)::type;
add<t1_type, t2_type>({}, {});
});
});
}
If you have boost at hand then boost::hana is definitely the way to go. However, it's not very hard to reimplement that feature by hand if you have to:
#include <iostream>
template<typename... T>
struct iterator {
template<typename CB_T>
static void iterate(CB_T const& ) {}
};
template<typename first, typename... rest>
struct iterator<first, rest...> {
template<typename CB_T>
static void iterate(CB_T const& cb) {
cb(first());
iterator<rest...>::iterate(cb);
}
};
int main() {
iterator<int, float>::iterate([](auto const & v_1){
using v_1_t = decltype(v_1);
iterator<char, double>::iterate([&](auto const & v_2){
using v_2_t = decltype(v_2);
std::cout << typeid(v_1_t).name() << " vs " << typeid(v_2_t).name() << "\n";
});
});
return 0;
}
I know, that there exists the possibility for automatic type deduction of function templates, given a particular function parameter, but does there also exist such a method for non type template parameters?
Example:
#include <iostream>
template<typename T, T val>
void func_a(void) {
std::cout << val << std::endl;
}
template<typename T>
void func_b(T val) {
std::cout << val << std::endl;
}
int main(void) {
func_a<uint32_t, 42u>();
//func_a<42u>(); //This line doesn't work
func_b(42u);
return 0;
}
So I don't want to give each time the template argument type uint32_t every time, when I call func_a(). Does there such a method exist in C++17 or below?
I am using g++ v.7.3 and c++17.
In C++17, you can use auto:
template<auto val>
void func_a(void) {
std::cout << val << std::endl;
}
int main(void) {
func_a<42u>();
return 0;
}
Given a +1 for the C++17 solution, a better-than-nothing C++11/C++14 solution can be the use of a macro to activate decltype() over the argument.
By example, with the macro
#define func_a_macro(val) func_a<decltype(val), val>
or better, as suggested by liliscent, to avoid problems with references
#define func_a_macro(val) \
func_a<std::remove_reference<decltype(val)>::type, val>
you can call
func_a_macro(42u)();
p.s.: I know... I know... macros are distilled evil... but sometime are useful.
C++14 solution with no macros:
template<int N> auto Int = std::integral_constant<int, N>{};
template<class T, T n>
constexpr auto foo(std::integral_constant<T, n> x)
{
std::cout << x.value << std::endl;
}
int main()
{
foo(Int<6>);
}
c++11:
template<int N> using Int = std::integral_constant<int, N>;
template<class T, T n>
constexpr void foo(std::integral_constant<T, n> x)
{
std::cout << x.value << std::endl;
}
int main()
{
foo(Int<6>());
}
Is it possible to write something like this?
[](std::index_sequence<std::size_t ...I> s) {
};
Or this?
[]<std::size_t ...I>(std::index_sequence<I...> s) {
}
How is the syntax for this in C++14 or C++17? Or is it not possible at all? Basically, I just want to have the I as a template parameter pack, and the lambda just serves as a way to do that. Alternatively, is there a syntax to achieve the following?
std::index_sequence<std::size_t ...I> x = std::make_index_sequence<10>{};
// I now is a local template parameter pack
GCC provides the latter syntax as an extension, but it's not standard:
template <typename... Ts>
void foo(const std::tuple<Ts...>& t) {
auto l = [&t]<std::size_t ...I>(std::index_sequence<I...> s) {
std::initializer_list<int>{ (std::cout << std::get<I>(t), 0)... };
};
l(std::index_sequence_for<Ts...>{});
}
Live Demo
Not exactly the same, but maybe you can push the sequence with an helper function as it follows:
#include <functional>
#include <cstddef>
#include <iostream>
auto lambda = [](auto... I){
int arr[] = { (std::cout << I << std::endl, 0)... };
(void)arr;
};
template<std::size_t... I>
constexpr auto f(std::index_sequence<I...>) {
return lambda(I...);
}
int main() {
f(std::make_index_sequence<3>());
}
I have the next code:
object a,b,c;
fun (a);
fun (b);
fun (c);
I wonder if it is there any way to do something similar in C++98 or C++11 to:
call_fun_with (fun, a, b, c);
Thanks
Here a variadic template solution.
#include <iostream>
template < typename f_>
void fun( f_&& f ) {}
template < typename f_, typename head_, typename... args_>
void fun( f_ f, head_&& head, args_&&... args) {
f( std::forward<head_>(head) );
fun( std::forward<f_>(f), std::forward<args_>(args)... );
}
void foo( int v ) {
std::cout << v << " ";
}
int main() {
int a{1}, b{2}, c{3};
fun(foo, a, b, c );
}
You may use the following using variadic template:
template <typename F, typename...Ts>
void fun(F f, Ts&&...args)
{
int dummy[] = {0, (f(std::forward<Ts>(args)), 0)...};
static_cast<void>(dummy); // remove warning for unused variable
}
or in C++17, with folding expression:
template <typename F, typename...Ts>
void fun(F&& f, Ts&&...args)
{
(static_cast<void>(f(std::forward<Ts>(args))), ...);
}
Now, test it:
void foo(int value) { std::cout << value << " "; }
int main(int argc, char *argv[])
{
fun(foo, 42, 53, 65);
return 0;
}
Using C++ 11, you can use std::function, this way (which is quite quick to write IMO)
void call_fun_with(std::function<void(int)> fun, std::vector<int>& args){
for(int& arg : args){
fun(arg);
}
}
or, a bit more generic:
template<typename FTYPE>
void call_fun_with(FTYPE fun, std::vector<int>& args){
for(int& arg : args){
fun(arg);
}
}
Live example
Live example, templated version
Note: std::function template arguments must be specified the following way: return_type(arg1_type, arg2_type,etc.)
EDIT: An alternative could be using std::for_each which actually does pretty much the same thing, but which I do not really like as to the semantics, which are more like "for everything in this container, do...". But that's just me and my (maybe silly) way of coding :)
A C++11 range-based (enhanced) for loop will recognise a braced-init-list as an initializer_list, which means something like the following will work:
for (auto &x : {a,b,c}) fun(x);
there are a lot of different way's...
#include <iostream>
#include <vector>
#include <algorithm>
void foo(int x) {
std::cout << x << "\n";
}
void call_fun_with(std::function<void(int)> fn, std::vector<int> lst) {
for(auto it : lst)
fn(it);
}
int main() {
std::vector<int> val = {1,2,3,4,5};
// c++98
std::for_each(val.begin(), val.end(), foo);
// c++11
// vector
call_fun_with(foo, val);
// c++11
// initializer_list
int a=0, b=1, c=2;
call_fun_with(foo, {a,b,c});
}
see here.
I need something that is the opposite of std::bind, that adds dummy parameters to a function signature instead of how boost::bind binds parameters away.
e.g. I have this function:
std::function<void (void)> myFunc;
But I want to convert it into a std::function<void(int)> to pass into this function
void processFunction( std::function<void(int)> func);
Edit Oh, I mentioned the obvious in chat:
#EthanSteinberg: lambdas?
[] (int realparam, int dummy) { return foo(realparam); }
But it was dismissed, which is why I jump to:
Edit I just realized a much simpler approach: http://ideone.com/pPWZk
#include <iostream>
#include <functional>
using namespace std::placeholders;
int foo(int i)
{
return i*2;
}
int main(int argc, const char *argv[])
{
std::function<int(int, int)> barfunc = std::bind(foo, (_1, _2));
std::cout << barfunc(-999, 21) << std::endl;
// or even (thanks Xeo)
barfunc = std::bind(foo, _2);
std::cout << barfunc(-999, 21) << std::endl;
}
Variadic Templates http://ideone.com/8KIsW
A somewhat longer answer based on variadic templates would result in possibly smaller code at the call site (if you wanted to wrap functions with a long argument list).
#include <iostream>
#include <functional>
int foo(int i)
{
return i*2;
}
template <typename Ax, typename R, typename... A>
struct Wrap
{
typedef R (*F)(A...);
typedef std::function<R(A...)> Ftor;
Wrap(F f) : _f(f) { }
Wrap(const Ftor& f) : _f(f) { }
R operator()(Ax extra, A... a) const
{ return _f(a...); /*just forward*/ }
Ftor _f;
};
template <typename Ax=int, typename R, typename... A>
std::function<R(Ax, A...)> wrap(R (f)(A...))
{
return Wrap<Ax,R,A...>(f);
}
template <typename Ax=int, typename R, typename... A>
std::function<R(Ax, A...)> wrap(std::function<R(A...)> functor)
{
return Wrap<Ax,R,A...>(functor);
}
int main(int argc, const char *argv[])
{
auto bar = wrap(foo);
std::function<int(int, int)> barfunc = wrap(foo);
std::cout << barfunc(-999, 21) << std::endl;
// wrap the barfunc?
auto rewrap = wrap(barfunc);
std::cout << rewrap(-999, -999, 21) << std::endl;
return 0;
}
Generalizing from this would require some more heavy lifting. I think I've seen in the past helpers to 'dissect' (using meta-programming) the signature of a std::function<> and you should be able to make it recognize non-void functions, and perhaps even adding a parameter at the end or in the middle (tricky, as far as I can tell now).
But for your simple case from the OP, it looks like you're covered
You could use a lambda, if your implementation supports it:
processFunction([=](int a){ myFunc(); });