I don't know there is std::addressof available in c++ standard library until today I read some blog. In my understanding, if opeartor & is overloaded, then std::addressof should be used, otherwise it's not necessary to use std::addressof, it should be equivalent with &.
However, just trying to use std::addressof, to validate if it is the same as &, I meet compile error: "call to deleted function 'addressof' ". Don't know why.
Here's the minimal code to demonstrate this problem:
#include <iostream>
#include <memory>
class Foo
{
public:
Foo(int _len): len(_len) {
if(len>0) {
data = new double[len];
}
// compile error: call to deleted function 'addressof'
std::cout << "Foo() " << std::addressof(this) << "/" << std::addressof(data) << std::endl;
}
~Foo() {
// compile ok
std::cout << "~Foo() " << (void*)this << "/" << (void*)data << std::endl;
// compile error: call to deleted function 'addressof'
std::cout << "~Foo() " << std::addressof(this) << "/" << std::addressof(data) << std::endl;
if (data!=nullptr) {
delete[] data;
}
}
private:
int len;
double* data;
};
int main() {
Foo(42);
return 0;
}
C++ standard:
§9.3.2 The this pointer
the keyword this is a prvalue expression
std::addressof
template <class T>
const T* addressof(const T&&) = delete;
So addressof overload for rvalues is deleted. The reason is because you cannot take the address of a prvalue so addressof is modeled to respect that.
That's why you get the error.
Please note that addressof(this) and (void*) this are not even in the same ballpark. The equivalent of addressof(this) would be &this which also doesn't compile.
Related
I have to implement a simple "unique_ptr" class supporting only a constructor, destructor, –>, *, and release(). And I did below.
However, it feels weird to write "up.operator->()" to get the pointer p. I would be more logical to write "up->p". But how do I do that? Thanks!
#include <iostream>
#include <stdexcept>
template <class T>
class unique_ptr
{
T *p;
public:
unique_ptr(T *ptr)
: p{ptr}
{
}
~unique_ptr() { delete p; }
T *operator->() const { return p; } // returns a pointer
T operator*() const { return *p; }
T *release()
{
T *ptr = p;
p = nullptr;
return ptr;
}
};
template <class T>
void print(const unique_ptr<T> &up, const std::string &s)
{
std::cout << s << " up.operator->(): " << up.operator->() << '\n';
std::cout << s << " up.operator*(): " << up.operator*() << '\n';
}
int main()
try
{
int *ptr = new int(10);
unique_ptr<int> up(ptr);
print(up, "up: ");
}
catch (std::exception &e)
{
std::cerr << "exception: " << e.what() << '\n';
return 1;
}
catch (...)
{
std::cerr << "exception\n";
return 2;
}
However, it feels weird to write "up.operator->()" to get the pointer p.
It feels weird because the member access operator is not generally used to get a pointer to the object (although you can do it using the operator->() syntax, as you demonstrated). Member access operator is used to access members of the object. In your example, you have a unique pointer of int. int doesn't have a member, so it doesn't make sense to use the member access operator.
Here is an example of how to use it:
struct S {
int member;
};
unique_ptr<S> up(new S{10});
int value_of_member = up->member;
would be more logical to write "up->p"
That wouldn't be logical unless p is a member of the pointed object.
How to create an operator-> for a class unique_ptr
Like you did in the example. As far as I can tell, there was no problem with how you create the operator, but rather how to use it.
P.S. Your unique pointer is copyable, movable and assignable, but those operations are horribly broken leading to undefined behaviour. See rule of 5.
As others have noted in comments this implementation of a single ownership smart pointer is incomplete and the operator*() is incorrect in that it doesn't return a reference and thus does not facilitate making assignments through the pointer.
However to answer the question,
it feels weird to write "up.operator->()" to get the pointer p. I
would be more logical to write "up->p". But how do I do that?
Well you wouldnt want to do that as p is part of the private implementation of your smart pointer class. It is weird to write up.operator->() because that is not how the -> is typically used. It is typically used as shorthand to access the members of a struct or class that is slightly less verbose than the * operator in combination with member access via .. To use your pointer then in a less weird way you need the template parameter to be instantiated with some type that has fields, e.g.
struct foo {
int bar;
};
void print(const unique_ptr<foo>& up, const std::string& s)
{
std::cout << s << " up.operator->(): " << up->bar << '\n';
std::cout << s << " up.operator*(): " << (*up).bar << '\n';
}
int main()
{
unique_ptr<foo> up(new foo{ 42 });
print(up, "up: ");
}
I have read many posts about variadic templates and std::bind but I think I am still not understanding how they work together. I think my concepts are a little hazy when it comes to using variadic templates, what std::bind is used for and how they all tie together.
In the following code my lambda uses the dot operator with objects of type TestClass but even when I pass in objects of type std::ref they still work. How is this exactly? How does the implicit conversion happen?
#include <iostream>
using std::cout;
using std::endl;
#include <functional>
#include <utility>
using std::forward;
class TestClass {
public:
TestClass(const TestClass& other) {
this->integer = other.integer;
cout << "Copy constructed" << endl;
}
TestClass() : integer(0) {
cout << "Default constructed" << endl;
}
TestClass(TestClass&& other) {
cout << "Move constructed" << endl;
this->integer = other.integer;
}
int integer;
};
template <typename FunctionType, typename ...Args>
void my_function(FunctionType function, Args&&... args) {
cout << "in function" << endl;
auto bound_function = std::bind(function, args...);
bound_function();
}
int main() {
auto my_lambda = [](const auto& one, const auto& two) {
cout << one.integer << two.integer << endl;
};
TestClass test1;
TestClass test2;
my_function(my_lambda, std::ref(test1), std::ref(test2));
return 0;
}
More specifically, I pass in two instances of a reference_wrapper with the two TestClass objects test1 and test2, but when I pass them to the lambda the . operator works magically. I would expect that you have use the ::get() function in the reference_wrapper to make this work but the call to the .integer data member works..
The reference unwrapping is performed by the result of std::bind():
If the argument is of type std::reference_wrapper<T> (for example, std::ref or std::cref was used in the initial call to bind), then the reference T& stored in the bound argument is passed to the invocable object.
Corresponding standardese can be found in N4140 draft, [func.bind.bind]/10.
It is important to note that with std::bind;
The arguments to bind are copied or moved, and are never passed by reference unless wrapped in std::ref or std::cref.
The "passed by reference" above is achieved because std::ref provides a result of std::reference_wrapper that is a value type that "wraps" the reference provided.
std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is frequently used as a mechanism to store references inside standard containers (like std::vector) which cannot normally hold references.
By way of an example of what bind's unwrapping of the reference does (without the bind);
#include <iostream>
#include <utility>
#include <functional>
int main()
{
using namespace std;
int a = 1;
auto b = std::ref(a);
int& c = b;
cout << a << " " << b << " " << c << " " << endl; // prints 1 1 1
c = 2;
cout << a << " " << b << " " << c << " " << endl; // prints 2 2 2
}
Demo code.
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
std::function<void()> f = std::bind(&Test::work, &test);
thread th(f);
th.join();
return 0;
}
As above code, I want to bind member function void work(void) of a class (let's name it Test) , but occurs compiler error saying that can not determine which overrided function to use.
I can not change class Test since it belongs to a lib, how to achieve my goal? Thanks in advance!
Why don't skip std::bind altogether and use a lambda?
auto fp = [&t]() { t.test()};
As a bonus, your executable size will be smaller and your compiler has much easier time to inline the code if appropriate.
By casting it to the correct type:
std::function<void()> f = std::bind( static_cast<int (Test::*)()>(&Test::work), &test);
When deducing the template arguments to bind, the compiler is not in a context that allows function overload resolution - to be simplistic about it, it hasn't got that far yet.
Having deduced that the first argument is indeed the name of a member function pointer, it finds that there are two functions of the same name but of different types.
At this stage, they're both equally valid candidates (from the point of template argument deduction), therefore it's ambiguous
A static cast disambiguates because we're pushing the compiler beyond the stage where it has to deduce a template type - we have taken on the responsibility to template type deduction ourselves - by specifying the type in the static_cast.
So now all it has to do is overload resolution.
#include <functional>
#include <thread>
#include <iostream>
using namespace std;
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
// only overload resolution required here
auto fp = static_cast<int (Test::*)()>(&Test::work);
// type is now unambiguous and overload resolution is already done
std::function<void()> f = std::bind(fp, &test);
thread th(f);
th.join();
return 0;
}
try this(member function ptr):
int main(){
Test test;
typedef int(Test:: *WKPtr)(void);
WKPtr p = &Test::work;
std::function<int()> f = std::bind(p, &test);
f();
return 0;
}
I see the C++11 documentation (http://en.cppreference.com/w/cpp/language/lambda) for lambda expressions states capture by value and reference are supported but not rvalue reference. The closest SO question I could find related to this is: How to capture a unique_ptr into a lambda expression?, but it seems like my use case doesn't require the use of std::bind.
Code
#include <iostream>
#include <memory>
class Foo
{
public:
explicit Foo(int value = 0) : mValue(value) {}
// The following items are provided just to be explicit
Foo(Foo &&other) = default;
Foo &operator=(Foo &&other) = default;
Foo(const Foo &other) = delete;
Foo &operator=(const Foo &other) = delete;
~Foo() {}
int mValue;
};
void bar(std::unique_ptr<Foo> f)
{
std::cout << "bar: " << std::dec << f->mValue << "\n";
}
int main()
{
{
std::unique_ptr<Foo> f(new Foo(22));
std::cout << "main: " << std::hex << f.get() << "\n";
// Call the bar function directly (requires using std::move)
bar(std::move(f));
std::cout << "main: " << std::hex << f.get() << "\n";
}
{
std::unique_ptr<Foo> f(new Foo(99));
std::cout << "main: " << std::hex << f.get() << "\n";
// Lamda expression captures 'f' by reference and then calls the bar function (again, requires using std::move)
auto fn = [&f](){ bar(std::move(f)); };
fn(); // Execute the closure
std::cout << "main: " << std::hex << f.get() << "\n";
}
return 0;
}
Example Output
main: 0x92e010
bar: 22
main: 0
main: 0x92e010
bar: 99
main: 0
By examining the output it appears this program is running correctly (i.e., the observed results are what I expected. However, I have the following questions.
Questions
Is using the closure equivalent to the code that calls the bar function directly?
I'm asking explicitly since the documentation (see beginning of the question) about lambda expressions didn't state anything about using std::move on captured references (i.e., I want to make sure this doesn't run afoul of undefined behavior or similar bad outcomes).
If the answer to the first question is "you can't use std::move on the captured reference", then what is the right way to do this (e.g., the std::bind solution, etc)?
Is using the closure equivalent to the code that calls the bar function directly?
Yes, they're equivalent in this code. Captured references aren't special in any way that I can think of: you have fully defined behavior, as long as f is in scope and can be moved from.
Assuming following code. There is class MyStream witch has template overloaded operator <<. There also is globally overloaded operator MyStream& operator << (MyStream&, const MyClass&). The confusing thing is generating (by compiler) different methods for two almost identical situations (see body of main() function). I supposed that global operator should be used in both cases but it isn't. Why so?
#include <iostream>
class MyStream;
class MyClass;
MyStream& operator << (MyStream& stream, const MyClass&);
class MyStream
{
public:
template <typename T>
MyStream& operator << (const T&)
{
std::cout << __FUNCTION__ << " " << typeid(T).name() << std::endl;
return *this;
}
};
class MyClass
{
};
MyStream& operator << (MyStream& stream, const MyClass&)
{
std::cout << __FUNCTION__ << " " << typeid(MyClass).name() << std::endl;
return stream;
}
int main(int, char**)
{
// 1. Used globally defined operator for MyClass
MyStream() << int() << MyClass();
std::cout << std::endl;
// 2. Template instantiation
MyStream() << MyClass();
std::cin.get();
return 0;
}
Output of program compiled with Microsift Visual C++ Compilers 9.0 (x86):
MyStream::operator << int
operator << class MyClass
MyStream::operator << class MyClass
// 2. Template instantiation
MyStream() << MyClass();
In this case, the expression MyStream() creates a temporary object (a rvalue) which cannot be bound to non-const reference, so the compiler chooses the member function template, because in order to call the free function, the temporary object must be passed as first argument to the function, which is not possible here, as the type of first parameter of the free function is non-const reference. So MyStream << MyClass() invokes member function.
But when you write this:
// 1. Used globally defined operator for MyClass
MyStream() << int() << MyClass();
It first invokes the member function passing int(), and the member function returns an object of type MyStream& which now can be passed to free function as first argument (as it is no more a rvalue, it is now a lvalue), then it invokes the free function, passing object of type MyStream& as first argument and MyClass() as second argument.
This is interesting, and a similar thing happens here:
std::ostringstream printing the address of the c-string instead of its content