default value of const reference parameter - c++

Currently I have two functions:
void foo(const A & a) {
...
result = ...
result += handle(a); // 1
bar(result);
}
void foo() {
...
result = ...
bar(result);
}
All code in foo() are the same except 1.
Can I merge them to one function like following?
void foo(const A & a = 0) {
...
...
if (a) result += handle(a); // this won't work, but can I do something similar?
bar(result);
}
Btw, the parameter has to be a reference as I would like to keep the interface unchanged.

You can use the Null Object Pattern.
namespace
{
const A NULL_A; // (possibly "extern")
}
void foo(const A & a = NULL_A) {
...
result = ...
if (&a != &NULL_A) result += handle(a);
bar(result);
}

No. A reference is always an alias for a real object (assuming you don't trigger undefined behavior). You can achieve similar behavior without code duplication by accepting a pointer instead:
void foo_impl(A const* obj) {
// code as before, except access obj with -> rather than .
}
void foo (A const& obj) {
foo_impl(&obj);
}
void foo() {
foo_impl(nullptr);
}

In the spirit of DRY, why not merge them as such?
void foo(const A & a) {
foo();
handle(a);
}
void foo() {
...
...
}

The entire idea of using reference is that you avoid the NULL pointer issue. The reference nothing but an alias for the real object. I have an another simple idea for your program, basically you want to achieve two functionality with same function - using default parameters. Here is the code. Please excuse me for the variable names.
class ABC
{
public:
int t;
ABC operator=(ABC& other)
{
other.t = 0;
}
};
ABC other;
void foo( ABC &a=other);
void foo( ABC &a)
{
if( a.t == 0)
qDebug()<<"The A WAS ZERO";
else
qDebug()<<"THE A isn't zero";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ABC hello;
hello.t = 100;
foo();
foo(hello);
return a.exec();
}
Here is the output.
The A WAS ZERO
THE A isn't zero

Use a base class that provides an interface, and two derived classes that implement the interface, one using A and the other using nothing.
Refactor foo to use a common foo.
struct Handler
{
virtual int get() = 0;
};
struct AHandler : Handler
{
AHandler(const A& a) : a_(a) {}
virtual int get() { return handle(a_); }
const A& a_;
}
struct NullHandler : Handler
{
virtual int get() { return 0; }
}
void foo(const Handler & h) {
...
result = ...
result += h.get();
bar(result);
}
void foo(const A & a) {
AHandler ah(a);
foo(ah);
}
void foo() {
NullHandler nh(a);
foo(nh);
}

Related

Is this indirect const access an UB?

When I was checking some code today, I noticed an old method for implementing std::enable_shared_from_this by keeping a std::weak_ptr to self in the constructor. Somthing like this:
struct X {
static auto create() {
auto ret = std::shared_ptr<X>(new X);
ret->m_weak = ret;
return ret;
}
// use m_weak.lock() to access the object
//...
private:
X() {}
std::weak_ptr<X> m_weak;
};
But then something came to me regarding constness of this object. Check the following code:
struct X {
static auto create() {
auto ret = std::shared_ptr<X>(new X);
ret->m_weak = ret;
return ret;
}
void indirectUpdate() const {
m_weak.lock()->val = 1;
}
void print() const {
std::cout << val << '\n';
}
private:
X() {}
std::weak_ptr<X> m_weak;
int val = 0;
};
int main() {
auto x = X::create();
x->print();
x->indirectUpdate();
x->print();
}
In this code, indirectUpdate() is a const method and it should not update our object, but in fact it does. Because std::weak_ptr.lock() returns a non-const shared_ptr<> even though the method is const. So you will be able to update your object indirectly in a const method. This will not happen in case of std::enable_shared_from_this because shared_from_this returns a shared pointer to const ref of object in const method. I wonder if this code is UB or not. I feel it should be, but I'm not sure. Any idea?
Update:
Sorry, it seems that my question was not relayed correctly. I meant even if we have a const pointer, we lose that constness via this method. following code shows that:
struct X {
static auto create() {
auto ret = std::shared_ptr<X>(new X);
ret->m_weak = ret;
return ret;
}
void show() const { std::cout << "const \n";}
void show() { std::cout << "non-const\n";}
void indirectUpdate() const {
show();
m_weak.lock()->show();
m_weak.lock()->val = 1;
}
void print() const {
std::cout << val << '\n';
}
int val = 0;
private:
X() {}
std::weak_ptr<X> m_weak;
};
int main() {
// Here we have a const pointer
std::shared_ptr<const X> x = X::create();
x->print();
x->indirectUpdate();
x->print();
}
and output will be following:
0
const
non-const
1
which shows losing constness.
The object that is modified is not const. There is no undefined behavior.
Add a method like this:
#include <memory>
#include <iostream>
struct X {
static auto create() {
auto ret = std::shared_ptr<X>(new X);
ret->m_weak = ret;
return ret;
}
void show() const { std::cout << "const \n";}
void show() { std::cout << "non-const\n";}
void indirectUpdate() const {
m_weak.lock()->show();
m_weak.lock()->val = 1;
}
void print() const {
std::cout << val << '\n';
}
private:
X() {}
std::weak_ptr<X> m_weak;
int val = 0;
};
int main() {
auto x = X::create();
x->print();
x->indirectUpdate();
x->print();
}
To get this output:
0
non-const
1
Modifying an object via a const mehtod is ok, as long as the method only modifies an object that is actually not const.
It is similar to using a const & to a non-const object. You may cast away constness and modify it as long as the object is really not const:
#include <iostream>
int main() {
int x = 0;
const int& ref = x;
const_cast<int&>(ref) = 42;
std::cout << x;
}
I also see no danger of misusing the pattern in your code, because once the object is const you won't be able to assign to its val member and all is fine with constcorrectness.
In your Update you have a const pointer in main but the object is still not const. Consider this simpler example:
#include <iostream>
struct foo {
static foo* create(){
auto x = new foo();
x->self = x;
return x;
}
void bar() const {
this->self->non_const();
}
void non_const() {
std::cout << "Hello World\n";
}
foo* self;
};
int main() {
const foo* f = foo::create();
f->bar();
delete f;
}
Its not quite the same as yours, but it has similar effect of calling a non-const method on a seemingly const object. Though its all fine.
The only foo object is that created in foo::create, it is not constant. In main we have a const foo* to that object. main can only call the const member bar. Inside bar the this pointer is a const foo*, but self does not point to a const foo. self itself is `const, but not the object it points to.

compile time selection of a specific method, disguised as an operator

I have a class like this one:
struct Base
{
void aa(int n) const {
std::cout << "aa() " << field*n << std::endl;
}
void bb(int n) const {
std::cout << "bb() " << field*n*2 << std::endl;
}
int field = 2;
};
I want to be able to select, at compile time, one of the two implementations, aa() or bb(), via a call to an operator method. Something like:
Base data;
Magic obj(data);
obj.as_AA() * 33; // should call data.aa(33)
obj.as_BB() * 44; // should call data.bb(44)
data must not be duplicated. And the choice of aa() vs bb() must be resolved at compile time.
I have a solution which uses a downcasting whose behavior is in theory undefined (I think). It builds (with g++ and clang++) and runs perfectly, but still ...
struct AA : public Base
{
void operator*(int n) const {
return Base::aa(n);
}
};
struct BB : public Base
{
void operator*(int n) const {
return Base::bb(n);
}
};
struct Chooser
{
Base obj;
template<typename WHICH> // will be either AA or BB
const WHICH& as() const {
return static_cast<const WHICH&>( obj ); // downcasting
}
};
In main.cpp:
Chooser ch;
ch.as<AA>() * 5; // prints "aa() 10"
ch.as<BB>() * 7; // prints "bb() 28"
How unreliable is my solution? (because of the downcasting which is technically undefined)
Do you see alternatives?
Thanks
ps: of course I could trivially use
Base data;
data.aa(33);
data.bb(44);
but I really want to access the different implementations via the same name, ie., the operator*
I could also use a templated operator* in Base and have explicit template specializations, however that would force me to use an ugly syntax, which kind of voids the purpose of the operator:
struct Base {
\\...
template<int N> void operator*(int n) const;
};
template<> void Base::operator*<1>(int n) const {
aa(n);
}
Which requires:
Base data;
data.operator*<1>(44); // ugly
You could write the Magic class like this:
struct Magic {
Magic(Base &b) : b(b) {}
Base &b;
struct AA {
Base &b;
void operator*(int n) const {
return b.aa(n);
}
};
struct BB {
Base &b;
void operator*(int n) const {
return b.bb(n);
}
};
AA as_AA() { return AA{b}; }
BB as_BB() { return BB{b}; }
};
This avoids any inheritance by using composition instead. Also, there is no copy of the data object, since only references are being made to it.
Now you can use exactly the calling syntax that you want, and it has the right behavior:
Base data;
Magic obj(data);
obj.as_AA() * 33; // calls data.aa(33) -- prints 66
obj.as_BB() * 44; // calls data.bb(44) -- prints 176
Here's a demo.
One solution for using the same function name is to strongly type the argument:
struct AA {
int n;
};
struct BB {
int n;
};
void call(Base& base, AA arg) {
base.aa(arg.n);
}
void call(Base& base, BB arg) {
base.bb(arg.n);
}
...
Base data;
call(data, AA{33});
call(data, BB{44});
I took the liberty of getting rid of the operator overloading since this still accesses different implementations using the same name.
If you're trying to go further by having the same calling code with the selection being done in advance, you can use a higher-order function:
auto call_aa(Base& base) {
return [&](int n) { return base.aa(n); };
}
auto call_bb(Base& base) {
return [&](int n) { return base.bb(n); };
}
...
Base data;
auto aa = call_aa(data);
aa(33);
call_bb(data)(44);

Determine Class Implementation Dynamically via Constructor

I want to create a class which behaves a certain way - e.g. spits out certain values from a function double getValue(const int& x) const - based on a "type" that was passed into its constructor. Right now I have two methods:
Store the passed-in "type" and then evaluate a switch statement in getValue each time it is called in order to decide which implementation to use.
Use a switch statement on the passed-in "type" (in the constructor) to create an internal object that represents the desired implementation. So no switch required anymore in getValue itself.
Method 1 "appears" inefficient as switch is called every time I call getValue. Method 2 seems somewhat clunky as I need to utilise <memory> and it also makes copying/assigning my class non-trivial.
Are there any other cleaner methods to tackle a problem like this?
Code Example:
#include <memory>
enum class ImplType { Simple1, Simple2 /* more cases */ };
class MyClass1
{
private:
const ImplType implType;
public:
MyClass1(const ImplType& implType) : implType(implType) { }
double getValue(const int& x) const
{
switch (implType)
{
case ImplType::Simple1: return 1; /* some implemention */
case ImplType::Simple2: return 2; /* some implemention */
}
}
};
class MyClass2
{
private:
struct Impl { virtual double getValue(const int& x) const = 0; };
struct ImplSimple1 : Impl { double getValue(const int& x) const override { return 1; /* some implemention */ } };
struct ImplSimple2 : Impl { double getValue(const int& x) const override { return 2; /* some implemention */ } };
const std::unique_ptr<Impl> impl;
public:
MyClass2(const ImplType& implType) : impl(std::move(createImplPtr(implType))) { }
static std::unique_ptr<Impl> createImplPtr(const ImplType& implType)
{
switch (implType)
{
case ImplType::Simple1: return std::make_unique<ImplSimple1>();
case ImplType::Simple2: return std::make_unique<ImplSimple2>();
}
}
double getValue(const int& x) const { return impl->getValue(x); }
};
int main()
{
MyClass1 my1(ImplType::Simple1);
MyClass2 my2(ImplType::Simple1);
return 0;
}
Your code is basically mimicing a virtual method (sloppy speaking: same interface but implementation is chosen at runtime), hence your code can be much cleaner if you actually do use a virtual method:
#include <memory>
struct base {
virtual double getValue(const int& x) const = 0;
};
struct impl1 : base {
double getValue(const int& x) { return 1.0; }
};
struct impl2 : base {
double getValue(const int& x) { return 2.0; }
};
// ... maybe more...
enum select { impl1s, impl2s };
base* make_impl( select s) {
if (s == impl1s) return new impl1();
if (s == impl2s) return new impl2();
}
int main() {
std::shared_ptr<base> x{ make_impl(impl1) };
}
Not sure if this is what you are looking for. By the way, using <memory> should not make you feel "clunky", but instead you should feel proud that we have such awesome tools in c++ ;).
EDIT: If you dont want the user to work with (smart-)pointers then wrap the above in just another class:
struct foo {
shared_ptr<base> impl;
foo( select s) : impl( make_impl(s) ) {}
double getValue(const int& x) { return impl.getValue(x); }
};
now a user can do
int main() {
auto f1 { impl1s };
auto f2 { impl2s };
f1.getValue(1);
f2.getValue(2);
}
If you have a closed set of types you can choose from, you want std::variant:
using MyClass = std::variant<MyClass1, MyClass2, MyClass3, /* ... */>;
It doesn't use dynamic allocation - it's basically a type-safe modern alternative to union.
More object-oriented approach:
class Interface
{
public:
virtual int getValue() = 0;
};
class GetValueImplementation1 : public Interface
{
public:
int getValue() {return 1;}
};
class GetValueImplementation2 : public Interface
{
public:
int getValue() {return 2;}
};
class GeneralClass
{
public:
GeneralClass(Interface *interface) : interface(interface) {}
~GeneralClass()
{
if (interface)
delete interface;
}
int getValue() { return interface->getValue(); }
private:
Interface *interface;
};
So, in this case you can use it without any pointers:
int main()
{
GeneralClass obj1(new GetValueImplementation1());
GeneralClass obj2(new GetValueImplementation2());
cout << obj1.getValue() << " " << obj2.getValue();
return 0;
}
The output will be:
1 2
But in the case you should be careful with null pointers or use smart ones inside GeneralClass.

Why is the dtor being called (using annoymous/lambda func)

I am trying to mimic a finally like effect. So i thought i should run a quick dirty test.
The idea was to use Most Important const to stop destruction and to put the finally block in a lambda. However apparently i did something wrong and its being called at the end of MyFinally(). How do i solve this problem?
#include <cassert>
template<typename T>
class D{
T fn;
public:
D(T v):fn(v){}
~D(){fn();}
};
template<typename T>
const D<T>& MyFinally(T t) { return D<T>(t); }
int d;
class A{
int a;
public:
void start(){
int a=1;
auto v = MyFinally([&]{a=2;});
try{
assert(a==1);
//do stuff
}
catch(int){
//do stuff
}
}
};
int main() {
A a;
a.start();
}
My Solution code (Note: You can not have two finally in the same block. as expect. But still kind of dirty)
#include <cassert>
template<typename T>
class D{
T fn; bool exec;
public:
D(T v):fn(v),exec(true){}
//D(D const&)=delete //VS doesnt support this yet and i didnt feel like writing virtual=0
D(D &&d):fn(move(d.fn)), exec(d.exec) {
d.exec = false;
}
~D(){if(exec) fn();}
};
template<typename T>
D<T> MyFinally(T t) { return D<T>(t); }
#define FINALLY(v) auto OnlyOneFinallyPlz = MyFinally(v)
int d;
class A{
public:
int a;
void start(){
a=1;
//auto v = MyFinally([&]{a=2;});
FINALLY([&]{a=2;});
try{
assert(a==1);
//do stuff
}
catch(int){
FINALLY([&]{a=3;}); //ok, inside another scope
try{
assert(a==1);
//do other stuff
}
catch(int){
//do other stuff
}
}
}
};
void main() {
A a;
a.start();
assert(a.a==2);
}
Funny enough, if you remove the & in MyFinally in the original code it works -_-.
// WRONG! returning a reference to a temporary that will be
// destroyed at the end of the function!
template<typename T>
const D<T>& MyFinally(T t) { return D<T>(t); }
You can fix it my introducing a move constructor
template<typename T>
class D{
T fn;
bool exec;
public:
D(T v):fn(move(v)),exec(true){}
D(D &&d):fn(move(d.fn)), exec(d.exec) {
d.exec = false;
}
~D(){if(exec) fn();}
};
And then you can rewrite your toy
template<typename T>
D<T> MyFinally(T t) { return D<T>(move(t)); }
Hope it helps. No "const reference" trick is needed when you work with auto. See here for how to do it in C++03 with const references.
Your code and Sutter's are not equivalent. His function returns a value, yours returns a reference to an object that will be destroyed when the function exits. The const reference in the calling code does not maintain the lifetime of that object.
The problem stems from the use of a function maker, as demonstrated by Johannes.
I would argue that you could avoid the issue by using another C++0x facility, namely std::function.
class Defer
{
public:
typedef std::function<void()> Executor;
Defer(): _executor(DoNothing) {}
Defer(Executor e): _executor(e) {}
~Defer() { _executor(); }
Defer(Defer&& rhs): _executor(rhs._executor) {
rhs._executor = DoNothing;
}
Defer& operator=(Defer rhs) {
std::swap(_executor, rhs._executor);
return *this;
}
Defer(Defer const&) = delete;
private:
static void DoNothing() {}
Executor _executor;
};
Then, you can use it as simply:
void A::start() {
a = 1;
Defer const defer([&]() { a = 2; });
try { assert(a == 1); /**/ } catch(...) { /**/ }
}
Well the problem is explained by others, so I will suggest a fix, exactly in the same way Herb Sutter has written his code (your code is not same as his, by the way):
First, don't return by const reference:
template<typename T>
D<T> MyFinally(T t)
{
D<T> local(t); //create a local variable
return local;
}
Then write this at call site:
const auto & v = MyFinally([&]{a=2;}); //store by const reference
This became exactly like Herb Sutter's code.
Demo : http://www.ideone.com/uSkhP
Now the destructor is called just before exiting the start() function.
A different implementation which doesn't use auto keyword anymore:
struct base { virtual ~base(){} };
template<typename TLambda>
struct exec : base
{
TLambda lambda;
exec(TLambda l) : lambda(l){}
~exec() { lambda(); }
};
class lambda{
base *pbase;
public:
template<typename TLambda>
lambda(TLambda l): pbase(new exec<TLambda>(l)){}
~lambda() { delete pbase; }
};
And use it as:
lambda finally = [&]{a=2; std::cout << "finally executed" << std::endl; };
Looks interesting?
Complete demo : http://www.ideone.com/DYqrh
You could return a shared_ptr:
template<typename T>
std::shared_ptr<D<T>> MyFinally(T t) {
return std::shared_ptr<D<T>>(new D<T>(t));
}

How can I make this function act like an l-value?

Why can't I use the function ColPeekHeight() as an l-value?
class View
{
public:
int ColPeekHeight(){ return _colPeekFaceUpHeight; }
void ColPeekHeight( int i ) { _colPeekFaceUpHeight = i; }
private:
int _colPeekFaceUpHeight;
};
...
{
if( v.ColPeekHeight() > 0.04*_heightTable )
v.ColPeekHeight()-=peek;
}
The compiler complains at v.ColPeekHeight()-=peek. How can I make ColPeekHeight() an l-value?
Return the member variable by reference:
int& ColPeekHeight(){ return _colPeekFaceUpHeight; }
To make your class a good one, define a const version of the function:
const int& ColPeekHeight() const { return _colPeekFaceUpHeight; }
when I declare the function with the
two consts
When you want to pass an object into a function that you don't expect it to modify your object. Take this example:
struct myclass
{
int x;
int& return_x() { return x; }
const int& return_x() const { return x; }
};
void fun(const myclass& obj);
int main()
{
myclass o;
o.return_x() = 5;
fun(o);
}
void fun(const myclass& obj)
{
obj.return_x() = 5; // compile-error, a const object can't be modified
std::cout << obj.return_x(); // OK, No one is trying to modify obj
}
If you pass your objects to functions, then you might not want to change them actually all the time. So, to guard your self against this kind of change, you declare const version of your member functions. It doesn't have to be that every member function has two versions! It depends on the function it self, is it modifying function by nature :)
The first const says that the returned value is constant. The second const says that the member function return_x doesn't change the object(read only).
It can be rewritten like:
class View
{
public:
int GetColPeekHeight() const { return _colPeekFaceUpHeight; }
void SetColPeekHeight( int i ) { _colPeekFaceUpHeight = i; }
private:
int _colPeekFaceUpHeight;
};
...
{
cph = v.GetColPeekHeight();
if ( cph > 0.04 * _heightTable )
v.SetColPeekHeight( cph - peek );
}