Meaning of unique_ptr<const T> - c++11

Why unique_ptr can take owership of a const ptr?
What is the meaning of unique_ptr<const T>?
std::unique_ptr<int> a(new int);
// Only this is compile error.
std::unique_ptr<int> b((const int*)new int);
std::unique_ptr<const int> c(new int);
// Why unique_ptr can take a const ptr, and delete it when deconstruct?
std::unique_ptr<const int> d((const int*)new int);
Tested with g++ 4.8

Why unique_ptr can take owership of a const ptr?
Because even constant variables need to be destructed and freed when they are not longer needed. memory and resources leak happens on un-finalized variables regardless the const or volatile keywords.
What is the meaning of unique_ptr < const T>
Any meaning that uniqe_ptr<T> has , except it's const T and not T.
// Why unique_ptr can take a const ptr, and delete it when
deconstruct?
I have a feeling that you think that const object cannot be deleted, since they are const hence un-modifiable and un-destructable. this is wrong. the const kicks in after the variable has being constructed and "stop" taking affect on the variable destruction. otherwise, you couldn't create any const variable neither destroy them.

Related

In Metal Shading Language (MSL), how do I write pass-by-reference functions generic over address space?

I'm writing a Foo class for a Metal compute shader and want users to be able to add Foos regardless of the address space in which they reside. If I take the values by reference, this means I have to declare many permutations of which address spaces things live in:
class Foo {
private:
uint8_t bunchOfData[160];
public:
operator+(const thread Foo&) const thread;
operator+(const constant Foo&) cosnt thread;
operator+(const thread Foo&) const constant;
operator+(const constant Foo&) const constant;
// ... More overloads for local. For device, users should manually unpack to maintain coalescing.
}
Is there a way to genericize the address space qualifiers using templates?
Should I just use pass by value and dodge this whole problem entirely?
The size of Foo is non-trivial, like 160 bytes each.
When I last wrote compute kernels (i.e. 2009 era OpenCL), GPUs couldn't make function calls so pass-by-value vs pass-by-reference didn't really make a difference since everything got inlined anyways. Is this still the case?
If pass-by-reference is still useful, is it conventional to simply have the caller copy the value into thread space and only provide the thread-thread variant?
I've tried writing:
class Foo {
private:
uint8_t bunchOfData[160];
public:
template <typename T> operator+(const T& rhs) const;
}
but this gives me the error
error: reference type must have explicit address space qualifier
template <typename T> operator+(const T& rhs);
Not that I'm even specifying the address space of this correctly anyways...

g++ compiler error on deleted assignment operator of pair<string,string>

I think the following reduced C++11 code should be valid.
unordered_map<string,string> test;
auto it = remove_if( test.begin(), test.end(),
[] (const decltype(test)::value_type &entry) { return true; } );
But it fails to compile with g++ 6.3, complaining about a deleted assignment operator of std::pair, but AFAIK that operator is not deleted.
/usr/include/c++/6/bits/stl_algo.h:868:16: error: use of deleted function ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=( ...
*__result = _GLIBCXX_MOVE(*__first);
Is this a compiler/glibc bug or is the code really invalid for some reason I fail to see?
Let's look at remove_if documentation:
The type of dereferenced ForwardIt must meet the requirements of MoveAssignable.
That is, “given t, a modifiable lvalue expression of type T and rv, an rvalue expression of type T, the expression t = rv must be valid and [behave as expected]”.
Here, you pass unordered_map<string, string>'s iterator to remove_if. Let's have a look. According to unordered_map documentation,
value_type is defined as std::pair<const Key, T>
So, std::pair<const string, string>.
Let's look at pair's operator=. Most notably:
template< class U1, class U2 >
pair& operator=( const pair<U1,U2>& other ); does not participate in overload resolution unless std::is_assignable_v<first_type&, const U1&> and std::is_assignable_v<second_type&, const U2&> are both true.
Here, std::is_assignable_v<const string&, const string&> is not true, therefore the operator is not available. Therefore the pair is not MoveAssignable. Therefore remove_if cannot be used on those iterators.
So that would make your code invalid.
std::pair<const string, string> does have deleted assignment operator(s), because you can't change first.
The key_type of all the map-like containers in the STL are const, because otherwise you could break the lookup of elements.
I had a need to assign to a std::pair<A const, B> that was a copy of something I got by dereferencing a std::map<A,B> iterator. I finally used destructor/constructor logic.
// For the placement allocator
#include <new>
...
typedef std::pair<A const, B> PairType;
PairType &rPairWrite(...some source...);
PairType const &rPairRead(...some source...);
// rPairWrite = rPairRead;
rPairWrite.~PairType();
new (&rPairWrite) PairType (someAValue, someBValue);
Stupid syntax games...

C++ std::unique_ptr with custom deleter const conversion

The following code is valid in C++11 and can be used to convert to a const version of the underlying pointer type.
std::unique_ptr<int> a = std::unique_ptr<int>(new int(10));
std::unique_ptr<const int> b = std::move(a);
Is it possible to achieve the same thing when using a unique_ptr with a custom deleter?
std::unique_ptr<int, std::function<void(int*)>> a = std::unique_ptr<int, std::function<void(int*)>>(new int(10), [](int*){});
std::unique_ptr<const int, ???> b = std::move(a);
As I would expect (due to the different types) I get compiler errors whether I use int* or const int* for the deleter argument in the const definition.
Some context: I'm trying to typedef a drop-in replacement unique_ptr signature that works with a custom allocator and can be used wherever unique_ptr was used e.g.
template <typename T> using CustomUniquePtr = std::unique_ptr<T, std::function<void(???)>>;

Why constexpr data members are not implicitly static?

if you do this:
constexpr int LEN = 100;
LEN variable defined as const without need of typing const keyword.
It also have static storage, without need to type static keyword.
From the other hand, if we do same in class:
struct A{
constexpr static int SIZE = 100;
};
SIZE is still defined as const without need of typing const keyword,
However SIZE is not static data member.
You need to type static explicitly. If you don't there will be compilation error.
Question is:
What is the reason of need to explicitly type static?
static doesn't have same signification in both context :
for LEN, static means "only available in this compilation unit", so only internal linkage. It's a storage specifier
for A::SIZE, static means "it's a class member", so not bound to specific instances
constexpr in class context can refer to instance or class member or function, so compiler can't determine at your place if it's static or not, ie bound or not to a specific instance. It's same reasoning as const specifier. But, as you can imagine, it's a non-sense to have a non-static constexpr member, so it's forbidden. Example :
class A
{
int a;
constexpr A(int value): a(value) {}
// constexpr bound to a specific instance
constexpr int getDouble() const
{ return a*2; }
// constexpr not bound to a specific instance
static constexpr int getDouble(int b)
{ return b*2; }
}
constexpr in global context refers to something which will be calculated at compile time (or, for function, if not possible to calculate at compile time, which will be inlined), so no need of external linkage and so, comparable behavior as a static global variable or function (only comparable because, with compile time calculation or inlining, you also don't need internal linkage)
constexpr int a = 5; // Will be replace everywhere by value
/* If b is constexpr, calcul are done at compile time and result will be used
* else double is inlined, so no need of linkage at all
*/
constexpr int getDouble(int b)
{ return b * 2; }
constexpr should not imply static, because having constexpr
without static makes sense. Consider:
#include <iostream>
struct Dim
{
constexpr Dim(int a,int b) : a(a), b(b) {}
constexpr int Prod() const { return a*b; }
int a,b;
};
int main()
{
constexpr Dim sz(3,4);
int arr[ sz.Prod() ];
std::cout << sizeof(arr) << std::endl;
}
It should also not imply static outside of class definition
since static there means 'local to translation unit' and constexpr
does not require that.
I think you are confused about what static means at global scope, and your question is based on that misunderstanding.
LEN variable defined as const without need of typing const keyword.
Of course constexpr implies const, that shouldn't be surprising.
It also have static storage, without need to type static keyword.
N.B. a global variable always has static storage, because its lifetime is global. Adding the static keyword does not change that, what it does is give it internal linkage meaning it is not accessible by name outside the current translation unit.
That's the same rule for constexpr and const on global variables: a namespace-scope const variable implicitly has internal linkage (which is one of the many meanings of "static").
But a class-scope const variable does not have internal linkage, even if you add static to it. Marking a variable static means something completely different at namespace-scope and class-scope. It doesn't make sense to automatically add static to class members marked const or constexpr because that would mean something completely different than it does to variables at namespace-scope.
So constexpr implies const (obviously), and at namespace scope const implies internal linkage.
At class scope constexpr still implies const, but that doesn't have any effect on whether a member variable is a "class variable" or an "instance variable".

Does thread-safe mean const in c++11/14?

This question asks if const means thread-safe, which Herb Sutter's You don't know const and mutable talk answers well. But what about the opposite direction? If a function is thread-safe, should it thereby be marked const? If not, when should a function be marked const?
No, it's perfectly possible for a method to be non const but still be thread safe. Either it uses atomics, or a lock to protect member variables. For example, the count() method below is thread safe, whilst modifying the m_count member variable.
#include <iostream>
#include <mutex>
class Counter
{
public:
Counter() : m_counterMutex(), m_counter(0) {}
unsigned int count() {
std::lock_guard<std::mutex> lk(m_counterMutex);
++m_counter;
return m_counter;
}
private:
std::mutex m_counterMutex;
unsigned int m_counter;
};
It shouldn't be marked as const because the visible state has changed. It would surprise to users of the class that they could pass a const Counter& object to a function and the visible state of the object could be changed by that function.

Resources