I would like to initialize a boost rolling window accumulator without having to do an assignment inside a function call.
This is what I see everyone do:
boost::accumulators::accumulator_set<double, boost::accumulators::stats<boost::accumulators::tag::rolling_mean>> acc(boost::accumulators::tag::rolling_window::window_size = 10);
How could I make the same accumulator without having the assignment inside the constructor call above?
It's not an assignment, it's a named-argument idiom. C++ doesn't have that, really, so this why it looks like an assignment: it's an Expression Template
You could of course figure out the type and use it, but that would not make any difference and just make it harder to use the library correctly:
boost::parameter::aux::tagged_argument_list_of_1<
boost::parameter::aux::tagged_argument<
boost::accumulators::tag::rolling_window_size_<0>, const int>>
init(10);
ba::accumulator_set<double, ba::stats<ba::tag::rolling_mean>> acc(init);
I don't know about you, but I prefer the named-argument expression.
You can obviously write a helper function to remove the library details:
auto make_accum(int window) {
return ba::accumulator_set<
double,
ba::stats<ba::tag::rolling_mean>> (ba::tag::rolling_window::window_size = window);
}
int main() {
auto acc = make_accum(10);
}
This simply made the named argument into a positional argument using the knowledge about the statistics in in your set.
If you're worried about generic code, just pass the expression as the initializer in generic cases. That's how the library istelf is implemented:
template <typename Stats, typename... Init> auto generic_accum(Init const&... init) {
return ba::accumulator_set<double, Stats> (init...);
}
Demo All 3 Approaches
Live On Coliru
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>
namespace ba = boost::accumulators;
template <typename Stats, typename... Init> auto generic_accum(Init const&... init) {
return ba::accumulator_set<double, Stats> (init...);
}
auto make_accum(int window) {
return ba::accumulator_set<
double,
ba::stats<ba::tag::rolling_mean>> (ba::tag::rolling_window::window_size = window);
}
int main() {
{
boost::parameter::aux::tagged_argument_list_of_1<
boost::parameter::aux::tagged_argument<
boost::accumulators::tag::rolling_window_size_<0>, const int>>
init(10);
ba::accumulator_set<double, ba::stats<ba::tag::rolling_mean>>
acc(init);
}
{
auto acc = make_accum(10);
}
{
auto acc = generic_accum<ba::stats<ba::tag::rolling_mean>>(ba::tag::rolling_window::window_size = 10);
}
}
Related
Seems like everybody agrees that you need to avoid usage of raw loops e.g.
for (...)
{
...
}
the same is applied to while...
I'm looking for a best way to accomplish a mapping from std::list<type_a> to std::list<type_b> and follow this practice. My first guess is that I need to use standard algorithms. I would expect something like:
std::list<type_a> list_a= {...};
std::list<type_b> list_b= some_algorithms<type_b>(list_a);
What should I choose and how final solution will look like?
I strive to have the most elegant and efficient solution possible.
Yes it is possible to do this with std::transform too.
// convert list function
template<typename to_type, typename from_type>
std::list<to_type> convert_list(const std::list<from_type>& from_list)
{
std::list<to_type> to_list{ from_list.size() };
std::transform(from_list.cbegin(), from_list.cend(), to_list.begin(), [](const from_type& value) { return convert<to_type>(value); });
return to_list;
}
I think that any solution will have some kind of loop in there (even if it is hidden inside some standard library algorithm).
I took your line
std::list<type_b> list_b= some_algorithms<type_b>(list_a);
As a basis and came up with this.
#include <stdlib.h>
#include <list>
#include <string>
// in general converting items is just typecasting them
template<typename to_type, typename from_type>
to_type convert(const from_type& value)
{
return static_cast<to_type>(value);
}
// add specializations for conversion when needed, in this case int to std::string
template<>
std::string convert(const int& value)
{
return std::to_string(value);
}
// convert list function
template<typename to_type, typename from_type>
std::list<to_type> convert_list(const std::list<from_type>& from_list)
{
std::list<to_type> to_list;
for (const auto& value : from_list)
{
to_list.push_back(convert<to_type>(value));
}
return to_list;
}
int main()
{
std::list<int> values{ 0,1,42 };
auto string_values = convert_list<std::string>(values);
}
I have a lengthy unit test code snippet that I want to run for two functions. I am wondering if there's a way to do this without copy and paste the code and only change the function name?
Say the test code looks like
int main(){
output1 = function(input1);
assert output1 == answer1;
output2 = function(input2);
assert output2 == answer2;
output3 = function(input3);
assert output3 == answer3;
......
outputN = function(inputN);
assert outputN == answerN;
}
Now say I have two function func1 and func2. I want to ran literally the same test for func1 and func2. I am wondering if there's a neat way to do this in C++ without involving some test framework? Thanks in advance for any help.
You can make a function template:
template <typename F, typename R, typename Args...>
void test_func(F f, R&& r, Args&&... args) {
auto output = f(std::forward<Args>(args)...);
assert(output == std::forward<R>(r));
}
then use it like
test_func(&func1, answer1, input1);
test_func(&func2, answer2, input2);
...
Additional explanations:
The parameters and return value are passed by forwarding reference, then their value categories will be reserved when being passed to the function (with the usage of std::forward).
The parameters is declared as parameter pack then you can pass multiple ones with any types.
C++ supports passing parameters to functions ;).
You can pass functions to functions. To keep it simple, I am assuming that all functions you want to test have the same signature. To avoid verbose syntax of function pointers I'd use a template:
template <typename F>
void test_function(F f, std::vector<input_type> input,std::vector<output_type> expected) {
for (size_t i = 0; i < input.size(); ++i) {
assert( f(input[i]) == expected[i]);
}
}
int main() {
test_function( func1, {1,2,3},{2,3,4} );
test_function( func2, {1,2,3},{6,7,8} );
}
PS: From my own experience I can tell you that it isn't worth to put much work into hand-written test facilities. You will find yourself wanting more and more features that a test framework offers out of the box (eg logging test reports). Googletest is something I can recommend.
A solution of C methed is to use fuction pointer. But I recommand lambda fuction pulished in c++11. u can use as follow:
template<typename Func>
void test(intput in, output out, Func func) {
answer = func(in);
assert(out == answer);
}
void main() {
intput intput1;
output output1;
test(input1, output1, [&](intput in)->output{return func1(in)});
test(input1, output1, [&](intput in)->output{return func2(in)});
}
After all, u should add compile para:-std=c++11 while using g++ compiler.
Here's my new take, this should compile. It's built in layers so you can see how to expand each layer as you see fit. It doesn't work exactly as your example does, there are copies being made of your input data and there is no assignment operation for the output. You should take these into account and adjust accordingly (if required).
// Example program
#include <functional>
#include <assert.h>
#include <vector>
#include <utility>
// function to test
int func1(int p_param)
{
return p_param;
}
// function to test
int func2(int p_param)
{
return p_param;
}
// Test runner base
template <typename TFunction, typename TInput, typename TOutput>
void test_runner(TFunction f, std::vector < std::pair<TInput, TOutput> > p_testparameters)
{
for (auto pair : p_testparameters)
{
assert(f(pair.first) == pair.second);
}
}
// Specific test 1
template <typename TFunction>
void test1(TFunction f)
{
test_runner<TFunction, int, int>(f, { {1,1},{2,2},{3,3} });
}
// Specific test 2
template <typename TFunction>
void test2(TFunction f)
{
test_runner<TFunction, int, int>(f, { {10,10},{20,20},{30,30} });
}
// Run tests for function
template <typename TFunction>
void runTests(TFunction f)
{
test1(f);
test2(f);
}
int main() {
runTests(func1);
runTests(func2);
return 0;
}
I am new to variadic templates, and I'm having a difficult time implementing this container class. What I want is to take a list of types, and then create a std::tuple that holds std::vectors of each type. The specific difficulty I was having is "iterating" over this std::tuple.
I was reading this answer, and it mentions that you can use std::apply for this. I'm not sure if I understand the purpose of a "fold expression." Here's what I tried:
#include <iostream>
#include <tuple>
#include <vector>
template<typename... Types>
class VecCollection {
public:
std::tuple<std::vector<Types>...> m_stuff; // inside or outside?
VecCollection(unsigned vec_length, Types... things)
: m_stuff(std::make_tuple(std::vector<Types>(things)...))
{
std::apply(
[](auto&&... vecs) {
for(int i = 0; i < 3; ++i) {
vecs.push_back(Types()...);
}
},
m_stuff);
}
};
int main() {
VecCollection<int, float>(3, 2.6, 400);
return 0;
}
It compiles if I remove the apply call inside the constructor. I think the problem is Types().... Do I have access to each constructor in a general way?
Would it be easier if I just went back to run-time polymorphism and held onto a bunch of pointers to a base class for all these Types?
try this.
template<typename... Types>
class VecCollection {
public:
std::tuple<std::vector<Types>...> m_stuff; // inside or outside?
VecCollection(unsigned vec_length, Types... things)
: m_stuff(std::make_tuple(std::vector<Types>(things)...))
{
std::apply(
[](auto&&... vecs) {
for(int i = 0; i < 3; ++i) {
((vecs.push_back(Types()), ...));
}
},
m_stuff);
}
};
Suppose I have a class:
class Widget {
public:
void initialize() {
// hurr-durr
};
int computeAnswer() {
return -42;
};
std::string getQuestion() {
return "The question";
};
};
It performs some computation, can do whatever it wants.
Now I want to augment it - apply an aspect, say one that logs each method call.
If I implemented this by hand, I'd implement all methods in this fashion:
int LoggingWidget::computeAnswer(){
log << 'Calling method computeAnswer';
int result = Widget::computerAnswer();
log << 'Result = ' << result;
return result;
}
I'd like the solution to be as generic as possible (I don't want to manually forward all calls), so the possible usages could include one of these (whichever is possible)
Widget* w = new LoggingWidget(); // either a class that inherits from Widget
// and automatically forwards all calls.
Widget* w = new Logging<Widget>(); // or a template that does this.
so that when I call
int result = w.computeAnswer();
The calls will be logged. Perhaps the new ellipsis operator (...) could come in handy here?
This isn't directly possible, since you can't inspect a class to see which members it has.
However, you can do something close:
Logging<Widget> w(widget);
w([&](Widget& w){
return w.computeAnswer();
});
Where Logging::operator() looks like follows:
/* somewhere in class: T wrapped; */
template<class F>
auto operator()(F&& f)
-> decltype(f(wrapped))
{
pre_log();
auto&& result = f(wrapped);
post_log(result);
return result;
}
It won't get better much better than this for totally generic code, since C++ has no (static) reflection.
Expanding on Xeo's answer, if you use decltype or result_of rather than auto && you also get copy elision.
template<typename F>
auto operator()(F &&f) -> decltype(std::forward<F>(f)(wrapped))
{
pre_log();
decltype(std::forward<F>(f)(wrapped)) result = std::forward<F>(f)(wrapped);
post_log(result);
return result;
}
In C++14 you can shorten this to:
template<typename F>
decltype(auto) operator()(F &&f)
{
pre_log();
decltype(auto) result = std::forward<F>(f)(wrapped);
post_log(result);
return result;
}
I would like to know what is the correct type definition for the lambda presented below, so that the following code will compile using a conformant c++11 compiler:
#include <cstdio>
#include <string>
template<class Func>
class foo
{
public:
foo(Func func)
: fum(func){}
Func fum;
};
int main()
{
foo<???> fi([](int i) -> bool { printf("%d",i); return true; });
fi.fum(2);
return 0;
}
I guess another way it could be done is like so:
template<typename Func>
foo<Func> make_foo(Func f)
{
return foo<Func>(f);
}
int main()
{
auto fi = make([](int i) -> bool { printf("%d",i); return true; });
fi.fum(2);
return 0;
}
It's auto + decltype:
auto l = [](int i) -> bool { printf("%d",i); return true; };
foo<decltype(l)> fi(l);
fi.fum();
Every single lambda has a different, unique, unnamed type. You, as a coder, just can not name it.
However, in your case, since the lambda doesn't capture anything (empty []), it is implicitly convertible to a pointer-to-function, so this would do:
foo<bool(*)(int)> fi([](int i) -> bool { printf("%d",i); return true; });
fi.fum();
It's std::function<bool(int)>. Or possibly just bool(*)(int) if you prefer, since the lambda doesn't capture.
(The raw function pointer might be a bit more efficient, since std::function does (at least in some cases) require dynamic allocation for some type erasure magic.)