why iterating over unordered_map with unique_ptr forces a pair with a key that is const? - for-loop

I found a compiler error that I can not understand why it happens only for std::map with std::unique_ptr.
Assume we have the follow unoredered map object and an iteration code for it:
std::unordered_map<uint32_t, std::shared_ptr<char>> map;
for (const std::pair<uint32_t, std::shared_ptr<char>>& item : map)
{
// do something
}
That's compiled well, but if we use unique pointer instead the shared pointer as follows, then we get a compiler error about the iteration pair type:
std::unordered_map<uint32_t, std::unique_ptr<char>> map;
for (const std::pair<uint32_t, std::unique_ptr<char>>& item : map)
{
// do something
}
error C2440: 'initializing': cannot convert from 'std::pair<const _Kty,_Ty>' to
'const std::pair<uint32_t,std::unique_ptr<char,std::default_delete<_Ty>>>
Following this error, we can just add 'const' to the key type and it is compiled.
for (const std::pair<const uint32_t, std::unique_ptr<char>>& item : map)
^^^
|||
Why is this compiling error happens just for unique pointer?

A friend gave me the answer and I'm sharing.
The answer lies in the concept of implicit conversion(copy) a compiler is allowed to do.
Lets see the follow simple example:
const char x = 4;
const char& r = x; // r is reference for x. Checking their addresses yields the same
// address.
const int& ir = c; // implicit creation of object + conversion(copy).
// ir is different type of x, therefor compiler does implicit
// conversion(copy): it creates behind the scene an object of int,
// convert x into this temporary object. The temporary int object is
// then bound to the reference ir. Checking addresses of ir and x
// yields different addresses because ir is reference of the temporary
// object, not to x
So even we use reference - planning for just pointing on an existing object,
we may actually have an object construction + copy (if the types are different and there is conversion between them).
The same happens in the loop I gave in the question:
std::unordered_map<uint32_t, std::shared_ptr<char>> map;
for (const std::pair<uint32_t, std::shared_ptr<char>>& item : map)
{
// do something
}
while the real object held by the map is of type of
std::pair<const uint32_t, std::shared_ptr<char>>
the loop uses reference of different type:
std::pair<uint32_t, std::shared_ptr<char>>
and therefor, behind the scene, for every iteration, a new temporary object is implicitly constructed and a copy operation for conversion is done.
Not only that it isn't efficient, but it also failed to be compiled when the value is unique_ptr because the conversion does copy and unique_ptr can not be copied.
Thats why using 'auto' may save you such mistakes,
std::unordered_map<uint32_t, std::shared_ptr<char>> map;
for (const auto& item : map)
{
// do something
}
I myself sometimes prefer to play and use the explicit form instead 'auto' in order to face such problems and learn :)

Related

C++11 Pointer (void**)&data

I'm still learning C++, and I'm doing some API work, but I'm, having trouble parsing this pointer arrangement.
void* data;
res = npt.receive(0x1007, params, 1, response, (void**)&data, size);
uint32_t* op = (uint32_t*)data;
uint32_t num = *op;
op++;
Can anyone explain what is going on with that void pointer? I see it being defined, it does something in the res line(maybe initialized?), then it's copied to an uint32 pointer, and dereferenced in num. Can anyone help me parse the (void**)&data declaration?
Pay attention when you use the void pointer:
The void type of pointer is a special type of pointer. In C++, void represents the absence of type. Therefore, void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties).
This gives void pointers a great flexibility, by being able to point to any data type, from an integer value or a float to a string of characters. In exchange, they have a great limitation: the data pointed to by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason, any address in a void pointer needs to be transformed into some other pointer type that points to a concrete data type before being dereferenced.
From C++ reference
Firstly: What is npt?
Secondly: Guessing what npt could be some explanation:
// Declare a pointer to void named data
void* data;
// npt.receive takes as 5th parameter a pointer to pointer to void,
// which is why you provide the address of the void* using &data.
// The void ** appears to be unnecessary unless the data type of the
// param is not void **
// What is "npt"?
res = npt.receive(0x1007, params, 1, response, (void**)&data, size);
// ~.receive initialized data with contents.
// Now make the uint32_t data usable by casting void * to uint32_t*
uint32_t* op = (uint32_t*)data;
// Use the data by dereferencing it.
uint32_t num = *op;
// Pointer arithmetic: Move the pointer by sizeof(uint32_t).
// Did receive fill in an array?
op++;
Update
Signature of receive is:
<whatever return type> receive(uint16_t code, uint32_t* params, uint8_t nparam, Container& response, void** data, uint32_t& size)
So the data parameter is of type void** already so the explicit type cast to void** using (void**) is not necessary.
Considering the usage, the received data appears to be an array of uint32_t values IN THIS CASE!
Void as a type means no type and no type information regarding size and alignment is available, but is mandatory for lexical and syntactical consistency.
In conjunction with the *, it can be used as a pointer to data of unknown type and must be explicitly cast to another type (adds type information) before any use.
You usually have a void* or void** in an API, if you dont know the specific data type or only received plain byte data.
To understand this please read up C type erasure using void*
Please read up as basics before:
Dynamically allocated C arrays.
Pointers and Pointer Arithmetics.
From the code, ntp.receive tells you whether it receives anything successfully in the return code but it also needs to give you what it receives. It has a pointer that it wants to pass back, so you have to tell it where that pointer is so that it can fill it, hence (void **), a pointer to a pointer, being the address of your pointer, &data.
When you have received it, you know as the developer that what it points to is actually a uint_32 value so you copy the void pointer into one that points to a uint_32. In fact, this step is unnecessary since you could have cast the uint_32 pointer to void** in the above call but we'll let that slide.
Now that you have told the compiler that the pointer points to a 32 bit number, you can take the number on the other end of that pointer (*op) and store it in a local variable. Again, unnecessary, as *op could be used anywhere num is subsequently used.
Hope this helps.

Why does initialization of int by parenthesis inside class give error? [duplicate]

For example, I cannot write this:
class A
{
vector<int> v(12, 1);
};
I can only write this:
class A
{
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
};
Why is there a difference between these two declaration syntaxes?
The rationale behind this choice is explicitly mentioned in the related proposal for non static data member initializers :
An issue raised in Kona regarding scope of identifiers:
During discussion in the Core Working Group at the September ’07 meeting in Kona, a question arose about the scope of identifiers in the initializer. Do we want to allow class scope with the possibility of forward lookup; or do we want to require that the initializers be well-defined at the point that they’re parsed?
What’s desired:
The motivation for class-scope lookup is that we’d like to be able to put anything in a non-static data member’s initializer that we could put in a mem-initializer without significantly changing the semantics (modulo direct initialization vs. copy initialization):
int x();
struct S {
int i;
S() : i(x()) {} // currently well-formed, uses S::x()
// ...
static int x();
};
struct T {
int i = x(); // should use T::x(), ::x() would be a surprise
// ...
static int x();
};
Problem 1:
Unfortunately, this makes initializers of the “( expression-list )” form ambiguous at the time that the declaration is being parsed:
struct S {
int i(x); // data member with initializer
// ...
static int x;
};
struct T {
int i(x); // member function declaration
// ...
typedef int x;
};
One possible solution is to rely on the existing rule that, if a declaration could be an object or a function, then it’s a function:
struct S {
int i(j); // ill-formed...parsed as a member function,
// type j looked up but not found
// ...
static int j;
};
A similar solution would be to apply another existing rule, currently used only in templates, that if T could be a type or something else, then it’s something else; and we can use “typename” if we really mean a type:
struct S {
int i(x); // unabmiguously a data member
int j(typename y); // unabmiguously a member function
};
Both of those solutions introduce subtleties that are likely to be misunderstood by many users (as evidenced by the many questions on comp.lang.c++ about why “int i();” at block scope doesn’t declare a default-initialized int).
The solution proposed in this paper is to allow only initializers of the “= initializer-clause” and “{ initializer-list }” forms. That solves the ambiguity problem in most cases, for example:
HashingFunction hash_algorithm{"MD5"};
Here, we could not use the = form because HasningFunction’s constructor is explicit.
In especially tricky cases, a type might have to be mentioned twice. Consider:
vector<int> x = 3; // error: the constructor taking an int is explicit
vector<int> x(3); // three elements default-initialized
vector<int> x{3}; // one element with the value 3
In that case, we have to chose between the two alternatives by using the appropriate notation:
vector<int> x = vector<int>(3); // rather than vector<int> x(3);
vector<int> x{3}; // one element with the value 3
Problem 2:
Another issue is that, because we propose no change to the rules for initializing static data members, adding the static keyword could make a well-formed initializer ill-formed:
struct S {
const int i = f(); // well-formed with forward lookup
static const int j = f(); // always ill-formed for statics
// ...
constexpr static int f() { return 0; }
};
Problem 3:
A third issue is that class-scope lookup could turn a compile-time error into a run-time error:
struct S {
int i = j; // ill-formed without forward lookup, undefined behavior with
int j = 3;
};
(Unless caught by the compiler, i might be intialized with the undefined value of j.)
The proposal:
CWG had a 6-to-3 straw poll in Kona in favor of class-scope lookup; and that is what this paper proposes, with initializers for non-static data members limited to the “= initializer-clause” and “{ initializer-list }” forms.
We believe:
Problem 1: This problem does not occur as we don’t propose the () notation. The = and {} initializer notations do not suffer from this problem.
Problem 2: adding the static keyword makes a number of differences, this being the least of them.
Problem 3: this is not a new problem, but is the same order-of-initialization problem that already exists with constructor initializers.
One possible reason is that allowing parentheses would lead us back to the most vexing parse in no time. Consider the two types below:
struct foo {};
struct bar
{
bar(foo const&) {}
};
Now, you have a data member of type bar that you want to initialize, so you define it as
struct A
{
bar B(foo());
};
But what you've done above is declare a function named B that returns a bar object by value, and takes a single argument that's a function having the signature foo() (returns a foo and doesn't take any arguments).
Judging by the number and frequency of questions asked on StackOverflow that deal with this issue, this is something most C++ programmers find surprising and unintuitive. Adding the new brace-or-equal-initializer syntax was a chance to avoid this ambiguity and start with a clean slate, which is likely the reason the C++ committee chose to do so.
bar B{foo{}};
bar B = foo();
Both lines above declare an object named B of type bar, as expected.
Aside from the guesswork above, I'd like to point out that you're doing two vastly different things in your example above.
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
The first line initializes v1 to a vector that contains two elements, 12 and 1. The second creates a vector v2 that contains 12 elements, each initialized to 1.
Be careful of this rule - if a type defines a constructor that takes an initializer_list<T>, then that constructor is always considered first when the initializer for the type is a braced-init-list. The other constructors will be considered only if the one taking the initializer_list is not viable.

How do I check whether a std::function is bound to a specific object's member function?

I'm looking for a way of checking whether a std::function pointer is bound to a member function of a particular object. I'm aware that std::function itself has no '==' operator. I have however come across the std::function::target method which should be able, in principle, to give me the address of the function to which the pointer is pointing. My starting point was therefore this:
bool MyClass::isThePointerSetToMyMethod(std::function<void (const char*, string)> const& candidate)
{
// Create a pointer to the local reportFileError function using the same syntax that we did in the constructor:
std::function<void (const char *, string)> localFn = std::bind(&MyClass::theLocalMember, this,
std::placeholders::_1, std::placeholders::_2);
// Find the target
auto ptr1 = localFn.target< std::function<void (const char *, string)> >();
// Find the target of the candidate
auto ptr2 = candidate.target< std::function<void (const char *, string)> >();
// Compare the two pointers to see whether they actually point to the same function:
if (!ptr1 || !ptr2) return false;
if (*ptr1 == *ptr2)
return true;
else
return false;
}
This doesn't work, and the reason is that the values of 'ptr1' and 'ptr2' are always returned as null. According to the documentation for the std::function::target method, this must be because the type that I've specified for the target is not correct.
If I look at what target_type(localFn) actually is (using Visual C++ 2013), it's a bit frightening:
class std::_Bind<1,void,struct std::_Pmf_wrap<void (__thiscall MyClass::*)(char const *, string),void,class MyClass,char const *,string>,class MyClass * const,class std::_Ph<1> &,class std::_Ph<2> &>
Nevertheless, target_type(candidate) gives the same result, so I thought I'd try a typedef:
bool MyClass::isThePointerSetToMyMethod(std::function<void (const char*, string)> const& candidate)
{
typedef class std::_Bind<1,void,struct std::_Pmf_wrap<void (__thiscall MyClass::*)(char const *, string),void,class MyClass,char const *,string>,class MyClass * const,class std::_Ph<1> &,class std::_Ph<2> &> wally;
// Create a pointer to the local reportFileError function using the same syntax that we did in the constructor:
std::function<void (const char *, string)> localFn = std::bind(&MyClass::theLocalMember, this,
std::placeholders::_1, std::placeholders::_2);
// Find the target
auto ptr1 = localFn.target< wally >();
// Find the target of the candidate
auto ptr2 = candidate.target< wally >();
// Compare the two pointers to see whether they actually point to the same function:
if (!ptr1 || !ptr2) return false;
if (*ptr1 == *ptr2)
return true;
else
return false;
}
Alas this gets me no further; the values of ptr1 and ptr2 are still null.
So for now I've run out of ideas. Is there anyone reading this who knows either:
(1) The appropriate form for a typedef for a std::function pointer to the member function of a class, or
(2) A better way to achieve my ultimate objective, which is to tell whether a std::function pointer is pointing to a particular object's member function or whether it isn't?
[Background, in case anyone is interested: the reason I'm doing this is that I have a callback table where different callbacks are set to different functions depending on the state that the system is in; this makes state control very simple, as it means that in a given context I can call a given callback and know that the actions taken by the function I've called will be appropriate for the current state, without having to know anything about what that state actually is. Usually, when an object is instantiated which will change the system state, it takes control of the relevant callback(s) and binds them to whatever local member functions are appropriate for whatever state it's in. Under these circumstances, however, the object's destructor ought to return the callbacks to their status quo ante so that they are not left pointing to nothing.
Very rarely, an object may bind the callbacks to its member functions in its constructor, but before its destructor is called another object may take control of the same callbacks itself, and re-bind them to member functions of its own. If this happens, then the first object's destructor needs to be able to recognise that this has happened, and exit without affecting the callbacks' assignment to the second object's methods. The obvious way to do this is for the destructor to be able to check whether the callbacks are still assigned to its own methods or not, and if they are not then to leave well alone.]
Flesh out the callback table into a class which manages the table. All modifications to the table should be done through this class's interface. Internally, you would maintain a stack-like structure which lets you undo the changes done to the callback table. Barebones interface would look something like:
class CallbackTable
{
public:
bool ApplyChanges(...)
{
//Push the old values of the entries that would be changed here into your change-tracker stack and modify the table
}
bool UnApplyChanges(...)
{
//Pop the change-tracker stack and restore the table to the state it was in before the most recent change was applied.
}
};

C++11 - Moving fundamental data types in constructor?

I'm looking into move semantics from C++11 and I'm curious how to move fundamental types like boolean, integer float etc. in the constructor. Also the compound types like std::string.
Take the following class for example:
class Test
{
public:
// Default.
Test()
: m_Name("default"), m_Tested(true), m_Times(1), m_Grade('B')
{
// Starting up...
}
Test(const Test& other)
: m_Name(other.m_Name), m_Times(other.m_Times)
, m_Grade(other.m_Grade), m_Tested(other.m_Tested)
{
// Duplicating...
}
Test(Test&& other)
: m_Name(std::move(other.m_Name)) // Is this correct?
{
// Moving...
m_Tested = other.m_Tested; // I want to move not copy.
m_Times = other.m_Times; // I want to move not copy.
m_Grade = other.m_Grade; // I want to move not copy.
}
~Test()
{
// Shutting down....
}
private:
std::string m_Name;
bool m_Tested;
int m_Times;
char m_Grade;
};
How do I move (not copy) m_Tested, m_Times, m_Grade. And is m_Name moved correctly? Thank you for your time.
Initialization and assignment of a primitive from a prvalue or xvalue primitive has exactly the same effect as initialization or assignment from a lvalue primitive; the value is copied and the source object is unaffected.
In other words, you can use std::move but it won't make any difference.
If you want to change the value of the source object (to 0, say) you'll have to do that yourself.
Looks correct. Except simple data types like bool, int, char are only copied. The point of "moving" a string is that it has a buffer that it normally has to copy when constructing a new object, however when moving the old buffer is used (copying the pointer and not the contents of the buffer).
Test(Test&& other)
: m_Name(std::move(other.m_Name)), m_Times(other.m_Times)
, m_Grade(other.m_Grade), m_Tested(other.m_Tested)
{}

C++11 use-case for piecewise_construct of pair and tuple?

In N3059 I found the description of piecewise construction of pairs (and tuples) (and it is in the new Standard).
But I can not see when I should use it. I found discussions about emplace and non-copyable entities, but when I tried it out, I could not create a case where I need piecewiese_construct or could see a performance benefit.
Example. I thought I need a class which is non-copyable, but movebale (required for forwarding):
struct NoCopy {
NoCopy(int, int) {};
NoCopy(const NoCopy&) = delete; // no copy
NoCopy& operator=(const NoCopy&) = delete; // no assign
NoCopy(NoCopy&&) {}; // please move
NoCopy& operator=(NoCopy&&) {}; // please move-assign
};
I then sort-of expected that standard pair-construction would fail:
pair<NoCopy,NoCopy> x{ NoCopy{1,2}, NoCopy{2,3} }; // fine!
but it did not. Actually, this is what I'd expected anyway, because "moving stuff around" rather then copying it everywhere in the stdlib, is it should be.
Thus, I see no reason why I should have done this, or so:
pair<NoCopy,NoCopy> y(
piecewise_construct,
forward_as_tuple(1,2),
forward_as_tuple(2,3)
); // also fine
So, what's a the usecase?
How and when do I use piecewise_construct?
Not all types can be moved more efficiently than copied, and for some types it may make sense to even explicitly disable both copying and moving. Consider std::array<int, BIGNUM> as an an example of the former kind of a type.
The point with the emplace functions and piecewise_construct is that such a class can be constructed in place, without needing to create temporary instances to be moved or copied.
struct big {
int data[100];
big(int first, int second) : data{first, second} {
// the rest of the array is presumably filled somehow as well
}
};
std::pair<big, big> pair(piecewise_construct, {1,2}, {3,4});
Compare the above to pair(big(1,2), big(3,4)) where two temporary big objects would have to be created and then copied - and moving does not help here at all! Similarly:
std::vector<big> vec;
vec.emplace_back(1,2);
The main use case for piecewise constructing a pair is emplacing elements into a map or an unordered_map:
std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});
One power piecewise_construct has is to avoid bad conversions when doing overload resolution to construct objects.
Consider a Foo that has a weird set of constructor overloads:
struct Foo {
Foo(std::tuple<float, float>) { /* ... */ }
Foo(int, double) { /* ... */ }
};
int main() {
std::map<std::string, Foo> m1;
std::pair<int, double> p1{1, 3.14};
m1.emplace("Will call Foo(std::tuple<float, float>)",
p1);
m1.emplace("Will still call Foo(std::tuple<float, float>)",
std::forward_as_tuple(2, 3.14));
m1.emplace(std::piecewise_construct,
std::forward_as_tuple("Will call Foo(int, double)"),
std::forward_as_tuple(3, 3.14));
// Some care is required, though...
m1.emplace(std::piecewise_construct,
std::forward_as_tuple("Will call Foo(std::tuple<float, float>)!"),
std::forward_as_tuple(p1));
}

Resources