I want to create a function, where you can either use an int or a string variable as an parameter, but I don't know how.
I am writing a little example of what I want to achieve:
#include <iostream>
#include <string>
using namespace std;
int function((int a) || (string a))
{
...;
}
int main()
{
int intvar;
string stringvar;
function(intvar);
function(stringvar);
return 0;
}
Can I use logical operators with function paramenters?
No, you can't.
What you basically want is a function template or overload. The latter is the simplest way:
int function(int a)
{
// ...;
}
int function(string a)
{
// ...;
}
In case you have the same code for the varying types use a template:
template<typename T>
int function(T a)
{
static_assert(std::is_convertible<T,int>() || std::is_convertible<T,std::string>());
// ...;
}
You probably want to overload the function and call one from the other, something like:
int function(int a) {
// handle int parameter
}
int function(const string& s) {
int a = stoi(s);
return function(a);
}
Related
I have a structure that in its constructor receives an initialization list std::initializer_list<P...> of type parameter pack. That constructor is filled with lambda functions, and they are saved in a std::vector<P...>.
How can I get the return of those functions when traversing the vector calling each function?
Here is an example of the structure and what I want to do:
#include <iostream>
#include <functional>
#include <initializer_list>
using namespace std;
struct my_type {
my_type(){}
my_type(string _value) : value(_value) {}
string value = "test";
string getValue(){return value;}
};
template<typename A, class...P>
struct struct_name {
struct_name(std::initializer_list<P...> list) : functions(list) {}
std::vector<P...> functions;
string value;
my_type type;
string execute_functions(){
for (size_t i = 0; i < functions.size(); i++)
{
value = functions[i](type); // something like this, this does not work
}
return value;
std::cout << value;
}
};
typedef struct_name<std::function<void(my_type)>, std::function<void(my_type)>> _functions;
int main(int argc, char const *argv[])
{
_functions object = {
[](my_type var)->string{
return var.getValue();
},
[](my_type var)->string{
return var.getValue();
},
};
return 0;
}
Everything works perfect except the way to obtain those values. I don't know how, and no matter how hard I look I can't find answers.
EDIT: I can't paste the complete code, because it depends on many other classes. I tried to recreate that section, the type is a parameter pack because it receives multiple types besides lambdas, but in the example I just put it that way.
If you are trying to process a value through a series of function you can just use std::accumulate:
#include <iostream>
#include <vector>
#include <functional>
#include <numeric>
int main()
{
std::vector<std::function<float(float)>> functions = {
[] (float f) { return f*f; },
[] (float f) { return f + 2; }
};
float result = std::accumulate(functions.begin(), functions.end(), 1.5f,
[] (float v, const auto& lambda) {
return lambda(v);
}
);
std::cout << 1.5f << " -> " << result << std::endl;
return 0;
}
But a vector can only contain one specified type, so what you are trying to do with you parameter pack P... doesn't make much sense, if you want to process multiple values through multiple functions with different signatures you'd better try with something like std::tuple<std::function<T1(T2)>, std::function<T3(T4)>, ...> and pass multiple values to it.
You should be using std::tuple, if you want to store arbitrary callable objects.
You can combine std::index_sequence with a fold expression for calling the functions:
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
using std::string;
struct my_type {
my_type(){}
my_type(string _value) : value(_value) {}
string value = "test";
string getValue(){return value;}
};
template<class...P>
struct struct_name {
struct_name(P... args)
: functions(args...)
{}
std::tuple<P...> functions;
std::string value;
my_type type;
std::string execute_functions() {
return execute_helper(std::make_index_sequence<sizeof...(P)>{});
}
private:
template<size_t ...Is>
std::string execute_helper(std::index_sequence<Is...>)
{
((value += std::get<Is>(functions)(type)), ...);
return value;
}
};
int main()
{
struct_name foo(
[](my_type var)->string {
return var.getValue();
},
[](my_type var)->string {
return var.getValue();
});
std::cout << foo.execute_functions() << '\n';
return 0;
}
I need to define 3 functions that have the same goal, but whose behaviours changes slightly based on 3 sets of constant values; in other words, i could simply write a function that does that in all 3 cases by taking those values as inputs. But since there really many constants (and only 3 different sets of those) i'd definitely avoid such a long function declaration. Furthermore, i'll need those sets of constants in other files for related computations.
I was thinking about using namespaces, but i couldn't find anything that suited what i wanted to achieve. Just to make things more comprehensible, here is an example of what i'd desire (but obviously doesn't compile):
int parametric_function() {
return a_constant + 1; //'a_constant' isn't defined yet
}
namespace first_behaviour {
const int a_constant = 10;
//make the function use the variable 'a_constant' defined here in some way
int (*f)() = parametric_function;
}
namespace second_behaviour {
const int a_constant = 20;
//make the function use the variable 'a_constant' defined here in some way
int (*f)() = parametric_function;
}
As you can see, i'd only need to write my parametric function once, and i can use the namespace to get the right function and the associated set of constants. Do you have any suggestions on what i could try doing?
If you have only one variable, you can pass it directly as a template parameter, as suggested in this answer.
But if you have more than one, you can wrap them in a struct:
#include <iostream>
struct FirstBehavior
{
static constexpr int a_constant = 10;
};
struct SecondBehavior
{
static constexpr int a_constant = 10;
};
template <typename T>
int ParametricFunction()
{
return T::a_constant + 1;
}
int main()
{
std::cout << ParametricFunction<FirstBehavior>() << '\n'; // 1
}
In c++ you have templates:
template <int a_constant>
int parametric_function() {
return a_constant + 1;
}
namespace first_behaviour {
auto f = parametric_function<10>;
}
Using HolyBlackCat's suggestion of a struct and a template, here would be one approach.
The struct is just a wrapper to hold the variable. In this example, I made it a stateful variable (non-const), static to the struct wrapper. It has the requirement to be the expected name by the parameteric_function.
I thought making the example use a non-const variable might be more generally applicable for other types, such as std::string or std::vector or whatever you may need.
The extern int (*f)(); was just to squelch a compiler warning.
#include <iostream>
using std::cout;
template <typename T>
int parametric_function() {
++T::a_variable;
return T::a_variable;
}
namespace first_behaviour {
struct VarHolder {
static inline int a_variable = 10;
};
extern int (*f)();
int (*f)() = ¶metric_function<VarHolder>;
} // first_behaviour
namespace second_behaviour {
struct OtherVarHolder {
static inline int a_variable = 20;
};
extern int (*f)();
int (*f)() = ¶metric_function<OtherVarHolder>;
} // second_behaviour
int main() {
int x = first_behaviour::f();
int y = second_behaviour::f();
cout << x << " " << y << "\n";
}
Possibly you could do with templates. You could:
template <int CONST_VAL>
int par_func();
template<>
int par_func<10>(){ return 4; }
template<>
int par_func<20>(){ return 1; }
template<>
int par_func<30>(){ return 9; }
You could then alias these names to some other function if you want, or you can leave them like this. This also ensures that only the specialisations can be used.
You can also do your example like:
template <int CONST_VAL>
int par_func(){
return CONST_VAL + 1;
}
You can then put this in an implementation file and explicilty instantiate only the ones you use, like:
template int par_func<10>();
You can use this the same way with your namespace model like:
namespace func1 {
int(* func)() = &par_func<10>;
}
namespace func2 {
int(* func)() = &par_func<20>;
}
Is it possible to define the typecast operator as a non-member global
function?
#include <stdio.h>
#include <stdlib.h>
typedef int hash_t;
struct wrap {
int v;
operator hash_t () {
hash_t h = v+1;
return h;
}
};
int main(int argc, char **argv) {
int v = 1;
hash_t h = (hash_t)wrap{v};
printf("%d\n", h);
return 0;
}
Instead of (hash_t)wrap{v} being able to write (hash_t)v would be helpful. Not shure how the syntax of the overload would be, but something like operator hash_t (int v) { ... } ? Or is the typecast operator only overloadable in with memberfunction of a class/struct?
I want to define a dictionary template <typename key> CDict and want to convert key to int to use it as a hash. But I dont want to dispatch the hash function depending on the type of key or use a virtual function and also be able to use int as type for key.... Instead I want to overload the (hash_t) typecast.
Is this possible with global typecast overloads (or dont they exits) ?
It seems what you actually want to do is call different functions depending on the type, the operator overload is not the right way to go about this.
Instead, you can create a free function to handle int specifically, and then delegate to a member function in the non-int case
using hash_type = int;
// handle int
hash_type my_hash(int i) {
return i;
}
// handle anything else
template <typename T>
hash_type my_hash(const T& t) {
return t.hash(); // use whatever pattern you want here
}
template <typename Key, typename Value>
struct CDict {
void insert(const Key& k, const Value& v) {
auto hash = my_hash(k); // calls correct overload
}
};
// a type with a hash member function
struct MyHashable {
hash_type hash() const {
return 0;
}
};
int main() {
CDict<int, double> c1;
c1.insert(3, 5.0);
CDict<MyHashable, char> c2;
c2.insert(MyHashable{}, 'a');
}
Don't create type names ending with _t, they are reserved
I would like to use an array for one time only, and would like to not having to declare a name for it, e.g, something like
int a,b,c;
void foo(int[],int);
...
a=1; b=2; c=3;
foo({a,b,c},3);
...
I am pretty sure this is not going to work, but how can I make it work?
If you use std::vector or std::array, things become easier.
void foo(std::vector<int> xs)
{
for (const auto& x : xs)
{
std::cout << x << ' ';
}
}
int main()
{
foo({ 10,11,12 });
}
If you want to use an array "literal" only once, consider an rvalue reference to std::array:
// Declaration:
template<size_t s>
void foo(std::array<int, s>&& arr) {
// ....
}
//Call:
foo(std::array<int, 3>{1,2,3});
Using std::vector or std::array as in Nicky C's answer is better.
But to answer your question as is, you may do:
void foo(int[],int);
int main()
{
foo(std::vector<int>{10, 11, 12}.data(), 3);
}
Another way not mentioned yet is to use a std::initializer_list.
#include <initializer_list>
void foo(std::initializer_list<int> lst,int i)
{
}
int main()
{
int a,b,c;
a=1; b=2; c=3;
foo({a,b,c},3);
}
or you could use a template.
template<typename T, std::size_t N>
void foo(const T (&lst)[N],int i)
{
}
Abstract
I have a class that stores a optimization problem and runs a solver on that problem.
If the solver fails I want to consider a sub-problem and solve using the same solver (and class).
Introduction
An optimization problem is essencially a lot of (mathematical) functions. The problem functions are defined outside the class, but the sub-problem functions are defined inside the class, so they have different types (e.g. void (*) and void (MyClass::*).
At first I thought that I could cast the member function to the non-member pointer-to-function type, but I found out that I cannot. So I'm searching for some other way.
Example Code
An example code to simulate my issue:
#include <iostream>
using namespace std;
typedef void (*ftype) (int, double);
// Suppose foo is from another file. Can't change the definition
void foo (int n, double x) {
cout << "foo: " << n*x << endl;
}
class TheClass {
private:
double value;
ftype m_function;
void print (int n, double x) {
m_function(size*n, value*x);
}
public:
static int size;
TheClass () : value(1.2), m_function(0) { size++; }
void set_function (ftype p) { m_function = p; }
void call_function() {
if (m_function) m_function(size, value);
}
void call_ok_function() {
TheClass ok_class;
ok_class.set_function(foo);
ok_class.call_function();
}
void call_nasty_function() {
TheClass nasty_class;
// nasty_class.set_function(print);
// nasty_class.set_function(&TheClass::print);
nasty_class.call_function();
}
};
int TheClass::size = 0;
int main () {
TheClass one_class;
one_class.set_function(foo);
one_class.call_function();
one_class.call_ok_function();
one_class.call_nasty_function();
}
As the example suggests, the member function can't be static. Also, I can't redefine the original problem function to receive an object.
Thanks for any help.
Edit
I forgot to mention. I tried changing to std::function, but my original function has more than 10 arguments (It is a Fortran subroutine).
Solution
I made the change to std::function and std::bind as suggested, but did not went for the redesign of a function with more 10 arguments. I decided to create an intermediate function. The following code illustrates what I did, but with fewer variables. Thanks to all.
#include <iostream>
#include <boost/tr1/functional.hpp>
using namespace std;
class TheClass;
typedef tr1::function<void(int *, double *, double *, double *)> ftype;
// Suppose foo is from another file. Can't change the definition
void foo (int n, int m, double *A, double *x, double *b) {
// Performs matrix vector multiplication x = A*b, where
// A is m x n
}
void foo_wrapper (int DIM[], double *A, double *x, double *b) {
foo(DIM[0], DIM[1], A, x, b);
}
class TheClass {
private:
ftype m_function;
void my_function (int DIM[], double *A, double *x, double *b) {
// Change something before performing MV mult.
m_function(DIM, A, x, b);
}
public:
void set_function (ftype p) { m_function = p; }
void call_function() {
int DIM[2] = {2,2};
if (m_function) m_function(DIM, 0, 0, 0);
}
void call_nasty_function() {
TheClass nasty_class;
ftype f = tr1::bind(&TheClass::my_function, this, _1, _2, _3, _4);
nasty_class.set_function(f);
nasty_class.call_function();
}
};
int main () {
TheClass one_class;
one_class.set_function(foo_wrapper);
one_class.call_function();
one_class.call_nasty_function();
}
PS. Creating a std::function with more than 10 variables seemed possible (compiled, but I didn't test) with
#define BOOST_FUNCTION_NUM_ARGS 15
#include <boost/function/detail/maybe_include.hpp>
#undef BOOST_FUNCTION_NUM_ARGS
But creating a std::bind for more than 10 arguments does not seem as easy.
std::function, std::bind, and lambdas are what you are looking for. In short, function pointers are very bad things and should be burned in fire. In long, std::function can store any function object which can be called with the correct signature, and you can use std::bind or a lambda to generate a function object that calls your member function quickly and easily.
Edit: Then you will just have to roll your own std::function equivalent that supports more than 10 arguments.