I have a method with the following definition:
void foo(int i = 0, bool flag = false) {}
I want to call foo() by passing only the second argument:
foo(true);
But like this it will always pass it to the first parameter (i).
Is there any other solution I can pass my argument to the second parameter ? Or the only way is to pass the first one also.
foo(0, true);
Technically no. But you can fake it with overloads, thusly:
void foo(bool flag)
{
foo(0,flag);
}
no. unlike python, you cannot explicitly state which parameter you want to have the value. you will have to call the method with all the parameters if you need the last one to be not the default.
It's not possible in C++, since it doesn't support named parameters: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.20
However you may use overloading:
void foo(int i, bool flag) {
//do stuff
}
inline void foo(int i) { foo(i, false); }
inline void foo(bool flag) { foo(0, flag); }
int main(void) {
foo(42);
foo(true);
return 0;
}
The former would include the base implementation and gets called by the latter ones.
Notice how they're inline.
No, when you want to pass only one parameter, you will pass the first. How the compiler could guess which parameter do you intend to use?
There's a nice "trick" called the named parameter idiom : http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.20
Here's a rough way you'd implement it for your code.
(Though its really only useful for cases where there's a lot more default/optional arguments)
class Foo
{
public:
//set the defaults
Foo():i_(100),flag_(false) {}
//provide the mutators
Foo& i(int in_i) { i_ = in_i; return *this; }
Foo& flag(int in_flag) { flag_ = in_flag; return *this; }
void operator() { foo( arg.i_, arg.flag_ ); } //Just forward to the full argument version
protected:
int i_;
bool flag_;
};
Now you can use it like this:
Foo()(); // First () creates temporary, second calls its operator()
Foo().i(20)();
Foo().flag(false)();
Foo().i(10).flag(false)();
There's some variants on this trick that you can use. You can put the arguments into a struct with mutators, but write a void foo(FooArgs) function. In this case you end up with something like:
foo( FooArgs().i(10) );
You can also call foo from from the Foo destructor rather than operator(). In that case your calls look like this:
Foo().i(20); // foo called when this temporary destructs
Related
I want to write an class that optimizes a parameter. I thought the following interface would be desirable:
class Optimization {
public:
std::shared_ptr<Part> getParameter() const {
return m_parameter;
}
void setParameter(const std::shared_ptr<Parameter>& parameter) {
m_parameter = parameter;
}
private:
std::shared_ptr<Paramter> m_parameter;
};
Now sometimes I may not be interested in the starting value of the parameter so I would like to call setParameter like this:
setParameter(std::make_shared(Parameter(...)));
(now I guess it makes more sense why there is a getter function)
So as I understand it the setParameter function is not taking advantage that I am passing an rvalue to setParameter.
So my question is how can I solve this?
Should I add another function
void setParameter(std::shared_ptr<Parameter>&& parameter) {
m_parameter = std::move(parameter);
}
Does this avoid unneccessary copies?
Or would a universal reference, maybe like this:
template<typename T>
void setParameter(T&& parameter) {
m_parameter = std::forward<T>(parameter);
}
be a better solution?
The right implementation is like below
void setParameter(std::shared_ptr<Parameter> parameter) {
m_parameter = std::move(parameter);
}
rvalue will be moved to parameter and parameter will be moved to m_parameter. Two moves, like you want.
lvalue will be copied to parameter and parameter will be moved to m_parameter. One copy and one move, the similar like with const reference, plus cheap moving that will be optimized.
You can read about this in the book "Effective C++" of Scott Meyers.
std::piecewise_construct is a constexpr flag which can be used to indicate piecewise construction of a data object.
Explanatory comments inline
#include <memory>
#include <utility>
struct Parameter
{
// some constructor
Parameter(int, int);
};
class Optimization {
public:
std::shared_ptr<Parameter> getParameter() const {
return m_parameter;
}
// original overload
void setParameter(const std::shared_ptr<Parameter>& parameter) {
m_parameter = parameter;
}
// rvalue overload
void setParameter(std::shared_ptr<Parameter>&& parameter) {
m_parameter = std::move(parameter);
}
// piecewise overload which forwards arguments
template<typename...Args>
void setParameter(std::piecewise_construct_t, Args&&...args)
{
m_parameter = std::make_shared<Parameter>(std::forward<Args>(args)...);
}
private:
std::shared_ptr<Parameter> m_parameter;
};
int main()
{
auto o = Optimization();
// original
o.setParameter(std::make_shared<Parameter>(1,2));
// equivalent to...
o.setParameter(std::piecewise_construct, 1, 2);
}
Suppose we have code like this:
template<class CALLBACK>
struct INIFile{
INIFile(CALLBACK &processor) :
processor(processor ){}
bool process(){
// lots of code here,
// call processor
processor(123);
return true;
}
CALLBACK &processor;
};
struct MyProcessor{
void operator()(int val){
// do something
}
};
struct MyConstProcessor{
void operator()(int val) const{ // !!!!!
// do something
}
};
int main(){
MyProcessor p;
INIFile<MyProcessor> ini(p);
ini.process();
// const case:
MyConstProcessor cp;
INIFile<MyConstProcessor> cini(cp);
cini.process();
}
In both cases INIFile<>::process() will be a non const member function.
Is there an easy way to make process() a const member function if CALLBACK::operator() is const, without duplicate all logic in INIFile<>::process()?
Your problem is solved by doing the following:
template<class CALLBACK>
struct INIFile{
INIFile(CALLBACK &processor) :
processor(processor){}
template <class T>
bool process_impl(T& processor) const {
// deliberately shadow processor
// reduce likelihood of using member processor, but can use other member variables
// lots of code
processor(123);
return true;
}
bool process() const {
return process_impl(const_cast<const CALLBACK&>(processor));
}
bool process() {
return process_impl(processor);
}
CALLBACK& processor;
};
This of course technically overloads process, but it has the exact same effect that you want. If the processor's call operator is not marked const, and you try to call process via a const reference or const copy of the object, you get a compilation error (unlike with your solution). That's because the const overload of process gets called, it adds the const to the processor which gets passed along, and then of course the call operator on the processor fails.
However, if the callback does provide a const call operator, then either process call will do exactly the same thing. This effectively means that you can call process on a const copy of INIFile, which is equivalent to process being const.
If the callback also overloads the call operator, then this implementation will forward along to whichever is correct, but you didn't specify that as a condition. The only thing to watch out for, is that process_impl should never access the member variable processor, because that member variable will always be mutable, i.e. the call will work even when it shouldn't (like in your solution). I shadow intentionally to try to prevent this. This isn't that beautiful but as an implementation detail it's not so bad, and it does remove the duplication.
Another way I found, but I do not like it very much is to use pointer instead of reference.
Here is the code.
Note in this particular case we do not need to check for nullptr at all.
template<class CALLBACK>
struct INIFile{
INIFile(CALLBACK &processor) :
processor(& processor ){}
bool process() const{
// lots of code here,
// call processor
processor->operator()(123);
return true;
}
CALLBACK *processor;
};
Is there a way in C++ to enforce function calls in compile time in such a way that this call will be allowed:
obj.reset().setParam1(10).setParam2(20);
but this one will fail to compile:
obj.reset().setParam1(10);
I want to avoid setting all parameters in one function since there are too many to be set; so I prefer to use something similar to named parameters idiom.
EDIT: Alternative syntax could be:
obj.reset(setParam1(10), setParam2(20));
or
obj.reset(setParam1(10).setParam2(20));
As the desired behaviour must be present at compile time, it needs to be implemented within the type system. To my understanding, this is impossible in C++ - the named parameters idiom relies on setter functions having the same return type (namely the type of the object which is called on), so calls to certain methods cannot be prevented.
I'll give you an example of doing that with the 2 parameters you provide, if you need more, it needs more work. If the requirement hierarchy between parameters get too complex, you may find it hard to structure your classes but here it goes:
class Obj {
Obj2 setParam2(int v);
}
class Obj2: public Obj {
Obj2 setParam1(int v);
}
int main() {
Obj obj;
obj.setParam2(10); // possible
obj.setParam2(10).setParam1(20); // possible
obj.setParam1(20); // not possible
obj.setParam1(20).setParam2(10); // unfortunately not possible
// Edit: one more limitation- consecutive calls are not possible,
// you must chain
obj.setParam2(20);
obj.setParam1(10); // problem
}
The best thing I could do to provide both named parameters and enforce all of them being initialized is this.
template<typename T>
struct Setter
{
Setter(const T ¶m) : ref(param) {}
const T &ref;
};
typedef Setter<int> Param1;
typedef Setter<std::string> Param2;
struct CObj
{
void reset(const Param1 &A, const Param2 &B) {
setParam1(A.ref); setParam2(B.ref); }
void setParam1(int i) { param1 = i; }
void setParam2(const std::string &i) { param2 = i; }
int param1;
std::string param2;
};
int main()
{
CObj o;
o.reset(Param1(10), Param2("hehe"));
}
The pseudo code for what I want to do is:
function<bool(int)> getFunc(type) // get a function depending on what type is passed
problem is the function to return must be declared as static? As a result, I can't access object properties. So I need to pass them into the function? Thus, the original function to return might look like:
bool func1(int)
bool func2(int)
Now needs to be injected with other objects/arguments it need to run ...
bool func1(int, Class1)
bool func2(int, Class2)
So how do I define the return type of getFunc? Or maybe theres a better way?
UPDATE
In the above, func* functions are actually: has*(). eg.
hasStmtsUsing(variable)
hasVariablesUsed(stmt)
And to determine if the condition is true, it uses an object eg. uses. Then there are other similar has*() functions like hasStmtsModifying(variable) that uses an object modifies. uses and modifies are objects of different types, and originally, they are object members, thus dont need to be passed in. Now since the functions are static, they need to be passed in.
While writing this, I am thinking what I need is some kind of dependency injector? Maybe I pass in DI and call DI.getX() functions?
Maybe I'm misunderstanding something, but isn't all you need to use a memberfunction where you bind() the first parameter?
class X {
bool f1(int);
bool f2(int);
};
X x;
function<bool(int)> f = bind(&X::f1, &x);
Here's an example of how it can be done with lambdas in C++11:
#include <cassert>
#include <functional>
#include <iostream>
struct Class1 {
};
struct Class2 {
};
bool func1(int,Class1)
{
return true;
}
bool func2(int,Class2)
{
return false;
}
inline std::function<bool(int)> getFunc(Class1 obj1)
{
return [=](int x){ return func1(x,obj1); };
}
inline std::function<bool(int)> getFunc(Class2 obj2)
{
return [=](int x){ return func2(x,obj2); };
}
int main(int,char**)
{
Class1 obj1;
std::function<bool(int)> f1 = getFunc(obj1);
Class2 obj2;
std::function<bool(int)> f2 = getFunc(obj2);
assert(f1(0)==true);
assert(f2(0)==false);
return 0;
}
I want to achieve something like this:
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo(int nVal = m_nVal)
{
// use nVal, if provided; otherwise use m_nVal
}
};
C c(1);
c.foo(); // use 1
c.foo(2); // use 2
This is not possible as C++ standard says:
a non-static member shall not be used in a default argument
Options I have are:
(1) Overload foo():
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo()
{
// use m_nVal
}
void foo(int nVal)
{
// use nVal
}
};
(2) Use static member:
class C
{
static int m_nVal;
public:
void foo(int nVal = m_nVal)
{
// use nVal, if provided; otherwise use m_nVal
}
};
I don't want to make m_nVal static member so option 1 seem the only one.
Are there any other ways to achieve this?
There are other alternatives if you are willing to change the interface. You can use boost::optional:
// untested:
void foo( boost::optional<int> val = boost::optional<int>() ) {
int value;
if ( val ) value = *val;
else value = m_val;
// Now use `value` in the function
}
If you cannot use boost, you can write your own nullable wrapper. You just need to store the type (int) and a flag that determines whether it is set or not.
The next option is using a pointer to mark that the argument is optional:
void foo( int *pval = 0 ) {
int value = (pval? *pval : m_val);
// use value from here on
}
But the option with the pointer inhibits the use of rvalues as arguments to the function (i.e. you need a proper variable to call the function, you cannot do foo(1) but rather need to do int x = 1; foo( &x );, which is kind of a pain).
Finally you can use your approach of offering two overloads, one that takes the argument and one that doesn't and just forwards to the first:
void foo( int val ) {
// actual implementation
}
void foo() {
foo( m_val );
}
This might actually be the best option...
The two options aren't equivalent. Making a member static shouldn't be a decision made on whether you want to use it as a default to a method or not.
If m_nVal is logically bound to the class, and not an instance, make it static.
If m_nVal is specific to each object of the class, don't, and use the first option.
Passing default parameter would mean compiler has to pass it. It would mean, for m_nVal, the compiler would use this->m_nVal. This would, in turn, mean `foo(this->m_nVal);'.
This is what I mean:
c.foo(c.m_nVal); // use 1
Which would allow m_nVal private data to be accessed outside class, and breaks basic C++ rule.
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo(int nVal = -1)
{
if(nVal == -1)
nVal = m_nVal;
// use nVal, if provided; otherwise use m_nVal
}
};
C c(1);
c.foo(); // use 1
c.foo(2); // use 2