Deleting all rvalue function overloads of a class - c++

Say I have a class object that must be captured by the caller when returning this class's object from a function call.
// no_can_rvalue *must* be captured
[[nodiscard]] no_can_rvalue a_func();
I can enforce this by deleting all rvalue function overloads, thus making it impossible to use the class functionality unless a caller has captured an object of it (doubled with nodiscard in c++17).
Is it possible to delete all rvalue function overloads of a given class in one fell swoop?
The result being equivalent to :
struct no_can_rvalue {
void f() && = delete;
void f() &;
void g() && = delete;
void g() &;
// etc
};

No, it is not possible to do so.

Related

Exception safety of std::function initialized by a function pointer

The constructor of std::function is not declared noexcept:
template< class F > function( F f );
On the other hand, C++ reference mentions the following:
Does not throw if f is a function pointer or a std::reference_wrapper,
otherwise may throw std::bad_alloc or any exception thrown by the copy
constructor of the stored callable object.
Does it mean that the constructor of the following class can be safely declared noexcept since I initialize std::function with a pointer to a static member function?
class Worker
{
public:
Worker() noexcept {} // ok?
void test() { reporter("test"); }
private:
static void dummy(const std::string& ) {};
std::function<void (const std::string&)> reporter = &dummy; // doesn't throw an exception?
};
int main()
{
Worker w;
w.test();
}
And if std::function member were constructed from a lambda, declaring the constructor noexcept would be wrong?
class Worker
{
public:
Worker() noexcept {} // bad?
void test() { reporter("Test"); }
private:
std::function<void (const std::string&)> reporter = [](const std::string& ){}; // may throw?
};
I have also noticed that GCC gives an error when the constructor declared noexcept is defaulted, because its exception specification does not match the implicit exception specification, which is noexcept(false) due to std::function constructor not being declared noexcept.
class Worker
{
public:
Worker() noexcept = default; // this won't compile
void test() { reporter("test"); }
private:
static void dummy(const std::string& ) {};
std::function<void (const std::string&)> reporter = &dummy;
};
Does it mean that the constructor of the following class can be safely declared noexcept since I initialize std::function with a pointer to a static member function?
Note that it's always "safe" to declare a function noexcept. The program will terminate if an exception is thrown, but it isn't undefined behavior.
But yes, in your case, no exceptions should be thrown, so no termination of the program should happen. The standard says: "Throws: Nothing if f is ... a function pointer. ..."
And if std::function member were constructed from a lambda, declaring the constructor noexcept would be wrong?
Yes, it'd be "wrong" in the sense you want (the program will terminate if it throws), because a lambda isn't a function pointer. Instead, prefix the lambda with the unary operator+ to make it a function pointer:
std::function<void (const std::string&)> reporter = +[](const std::string& ){};
And I'd probably mention this in a comment, in particular if you did not comment why the constructor is noexcept.
I have also noticed that GCC gives an error when the constructor declared noexcept is defaulted
The latest versions of both GCC and Clang do not give an error, so if that is true it is perhaps a Defect Report that was issued on the standard.

Explicit modifier for constructors taking reference argument

I read that it's a good practice to define single argument constructors explicit in order to avoid implicit conversions. I understand the pitfall of having int value promoted to class object. I wonder if it also applies to the constructors accepting reference types. How one can provoke implicit conversion in this case:
class Foo
{
public:
Foo(Bar& bar) { }
};
Does the situation changes if the constructor accepts pointers, is conversion from NULL and nullptr possible ?
class Foo
{
public:
Foo(Bar* bar) { }
};
Yes to both. A function with signature
void acceptFoo(const Foo& foo)
will make the compiler to create a Foo if you pass a Bar there.
Same for 0 and nullptr.

Initialize const member variables

I have C++ code that boils down to something like the following:
class Foo{
bool bar;
bool baz;
Foo(const void*);
};
Foo::Foo(const void* ptr){
const struct my_struct* s = complex_method(ptr);
bar = calculate_bar(s);
baz = calculate_baz(s);
}
Semantically, the bar and baz member variables should be const, since they should not change after initialization. However, it seems that in order to make them so, I would need to initialize them in an initialization list rather than assign them. To be clear, I understand why I need to do this. The problem is, I can't seem to find any way to convert the code into an initialization list without doing one of the following undesirable things:
Call complex_method twice (would be bad for performance)
Add the pointer to the Foo class (would make the class size needlessly large)
Is there any way to make the variables const while avoiding these undesirable situations?
If you can afford a C++11 compiler, consider delegating constructors:
class Foo
{
// ...
bool const bar;
bool const baz;
Foo(void const*);
// ...
Foo(my_struct const* s); // Possibly private
};
Foo::Foo(void const* ptr)
: Foo{complex_method(ptr)}
{
}
// ...
Foo::Foo(my_struct const* s)
: bar{calculate_bar(s)}
, baz{calculate_baz(s)}
{
}
As a general advice, be careful declaring your data members as const, because this makes your class impossible to copy-assign and move-assign. If your class is supposed to be used with value semantics, those operations become desirable. If that's not the case, you can disregard this note.
One option is a C++11 delegating constructor, as discussed in other answers. The C++03-compatible method is to use a subobject:
class Foo{
struct subobject {
const bool bar;
const bool baz;
subobject(const struct my_struct* s)
: bar(calculate_bar(s))
, baz(calculate_baz(s))
{}
} subobject;
Foo(const void*);
};
Foo::Foo(const void* ptr)
: subobject(complex_method(ptr))
{}
You can make bar and baz const, or make the subobject const, or both.
If you make only subobject const, then you can calculate complex_method and assign to bar and baz within the constructor of subobject:
class Foo{
const struct subobject {
bool bar;
bool baz;
subobject(const void*);
} subobject;
Foo(const void*);
};
Foo::Foo(const void* ptr)
: subobject(ptr)
{}
Foo::subobject::subobject(const void* ptr){
const struct my_struct* s = complex_method(ptr);
bar = calculate_bar(s);
baz = calculate_baz(s);
}
The reason that you can't mutate const members within a constructor body is that a constructor body is treated just like any other member function body, for consistency. Note that you can move code from a constructor into a member function for refactoring, and the factored-out member function doesn't need any special treatment.
You may use delegate constructor in C++11:
class Foo{
public:
Foo(const void* ptr) : Foo(complex_method(ptr)) {}
private:
Foo(const my_struct* s) : bar(calculate_bar(s)), baz(calculate_baz(s)) {}
private:
const bool bar;
const bool baz;
};
If you don't want to use the newfangled delegating constructors (I still have to deal with compiler versions that don't know about them), and you don't want to change the layout of your class, you could opt for a solution that replaces the constructor with const void * argument by a static member function returning Foo, while having a private constructor that takes the output from complex_method as argument (that latter much like the delegating constructor examples). The static member function then does the necessary preliminary computation involving complex_method, and ends with return Foo(s);. This does require that the class have an accessible copy constructor, even though its call (in the return statement) can most probably be elided.

Why do we treat a passed by reference values as an address?

I found this code:
foo::foo(const foo & arg) :
impl_(new impl(*arg.impl_))
{};
As far as I understand this constructor of class foo takes another object of the class foo as the only argument. What is not clear to me is why do we use * in front of arg. As far as I know, when we pass arguments by reference, we should treat this arguments in the "body" of the function as normal variables (and not as addresses of the variables, i.e. we should not use *).
The . operator has higher precedence than the indirection (*) operator, so your code is parsed as
*(arg.impl_)
impl_ appears to be a pointer, because you initialize it with new. To invoke the copy constructor, you have to pass an object, not a pointer, so you need to dereference it beforehand.
This is the copy constructor, and it takes a const reference (not an "object") as its argument.
You haven't shown the class definition, but
*arg.impl_
doesn't mean dereference arg and then look for some member called impl_, that would look like one of:
(*arg).impl_
arg->impl_
instead it means dereference the pointer arg.impl_, ie:
*(arg.impl_)
this is invoking the equivalent copy constructor for whatever type impl_ is.
Sample:
struct Impl {
int i_;
Impl() : i_(0) {}
Impl(const Impl& other) : i_(other.i_) {}
};
struct Foo {
Impl *impl_;
// Foo::Foo calls Impl::Impl
Foo() : impl_(new Impl()) {}
// Foo::Foo(const Foo&) calls Impl::Impl(const Impl&)
Foo(const Foo& other) : impl_(new Impl(*other.impl_)) {}
};
NB. this looks like the pimpl (or Pointer to Implementation) idiom.
Because impl_ is a pointer to a impl, which takes a a reference as copy constructor parameter (as is usually the case).

How does calling this function object work?

I have a class
class fobj{
public:
fobj(int i):id(i) {}
void operator()()
{
std::cout<<"Prints"<<std::endl;
}
private:
int id;
};
template<typename T>
void func(T type)
{
type();
}
If I invoke func like
Method 1:
func(fobj(1));
the message I wanted to print is printed.
I was always thinking I needed to do something like
Method 2:
fobj Iobj(1); // create an instance of the fobj class
func(Iobj); // call func by passing Iobj(which is a function object)
How does Method 1 work? I mean what exactly happens?
And how is a call made to the operator() in class fobj ?
One thing to note is that this works because your template class is taking an object by value:
template<typename T>
void func(T type) // this takes a T by value
...
because of this, it can take either an lvalue (such as an actual variable) or an rvalue (such as the temporary).
If for some reason you did want to limit func to only taking an lvalue, you could modify the function to using pass by reference:
template <typename T>
void func(T &type) // this takes a T by reference
...
using pass by reference does allow the side effect of the function being able to modify the object.
In func(fobj(1)), fobj(1) creates a temporay fobj from the literal int 1. This temporary is used to initialized the function parameter type (there's an implicit copy which the compiler may elide), and in the body of the function operator() is invoked on the function object.
I think that naming the function parameter type is a bit misleading. type is the name of the T instance (in this case a fobj) that is the function parameter.