The best way for me to describe what I am asking is a simple example.
template<typename T>
void execute_example(T* begin, T* end)
{
T val = 10 * 0.8;
while (begin != end)
{
*begin = val;
val *= 0.8;
++begin;
}
}
using var_t = std::variant<float*, int*, double*>;
// I am just going to assume the type in input is *float to save lines
template<class UnaryOperator>
void my_function(UnaryOperator unary_op, var_t input, size_t size)
{
if (input.index() != 0)
return;
float* begin = std::get<0>(input);
float* end = begin + size;
unary_op<float>(begin, end);
}
int main()
{
float* vals = new float[](10);
my_function(execute_example, vals, 10); // How can I pass execute_example here ??
delete[] vals;
}
What I am basically trying to figure out how to do is pass a function that needs a template as a function argument. For example, this would work, if instead of a template argument I just set T to float:
void execute_example(float* begin, float* end)
{
float val = 10 * 0.8;
while (begin != end) {
*begin = val;
val *= 0.8;
++begin;
}
}
using var_t = std::variant<float*, int*, double*>;
// I am just going to assume the type in input is *float to save lines
template<class UnaryOperator>
void my_function(UnaryOperator unary_op, var_t input, size_t size)
{
if (input.index() != 0)
return;
float* begin = std::get<0>(input);
float* end = begin + size;
unary_op<float>(begin, end);
}
int main()
{
float* vals = new float[](10);
my_function(execute_example, vals, 10); // works!!
delete[] vals;
}
Even if I changed my_function to the following, it still wouldn't work.
template<typename T>
void my_function(std::function<void(T*,T*)> unary_op, var_t input, size_t size)
Is there a way to do this? It seems like there should be because the following is also valid:
template<class UnaryOperator>
void my_function(UnaryOperator&& unary_op, var_t input, size_t size)
{
if (input.index() != 0)
return;
float* begin = std::get<0>(input);
float* end = begin + size;
std::forward<UnaryOperator>(unary_op)(begin, end);
}
int main()
{
float* vals = new float[10];
my_function([](auto* a, auto* b) {
typedef typename std::remove_pointer<decltype(a)>::type value_t;
value_t val = 10 * 0.8;
while (a != b) {
*a = val;
val *= 0.8;
++a;
}
}, vals, 10);
delete[] vals;
}
Which would do the same thing, and I would not have to specify a type.
while(begin != end)? Shouldn't you check<instead since you are multiplying thebeginpointer by some odd 0.8? Might be a noob observation on my part but I don't understand how this works..++beginincrements thebeginpointer, and then it eventually reaches the pointer declared asend. It is how most iterators work, I just happened to use a pointer which is entirely valid. I recommend you run the code and see that it terminates. You should look into iterators, and look at the documentation onstd::for_eachit follows a similar format. Also maybe watch some youtube videos on pointer arithmetic :)float * inputinstead and makemy_functiona non-template.//I am just going to assume the type in input is *float to save linesI wrote that purely for the readability. in practice I would use it for all the different types within a variant though.