I am implementing a default allocator for a simple containers library I'm writing, and I want to add an addressing-method that gets the memory address of the variable x that it works on, and that is also safe to use when x has overloaded the &-operator.
Looking into the MSVC STL source code I see that the function __builtin_addressof(your_variable) is used. Is this the only way? I also discovered the address method has been removed from the STL allocator in C++20, but I do not know if this was due to it not being used, or if there is a new and better method.
My implementation looks something like this:
namespace mem_core {
template <typename T>
const T* addressof(T& argument) noexcept {
return __builtin_addressof(argument);
}
template <typename T>
const T* addressof(T&& arg) = delete;
//... more mem_core stuff
} //namespace mem_core end
template <typename T>
class allocator : public mem_core::base_allocator<T> { // refers to base_allocator interface
public:
T* address(T& value) noexcept {
return mem_core::addressof(value);
}
}
There is std::addressof for exactly this purpose
Related
I have use case similar to this question
I want to check what type of instance variable is stored in parameter without throwing an exception
class ParameterBase
{
public:
virtual ~ParameterBase() {}
template<class T> const T& get() const; //to be implimented after Parameter
template<class T, class U> void setValue(const U& rhs); //to be implimented after Parameter
};
template <typename T>
class Parameter : public ParameterBase
{
public:
Parameter(const T& rhs) :value(rhs) {}
const T& get() const {return value;}
void setValue(const T& rhs) {value=rhs;}
private:
T value;
};
//Here's the trick: dynamic_cast rather than virtual
template<class T> const T& ParameterBase::get() const
{ return dynamic_cast<const Parameter<T>&>(*this).get(); }
template<class T, class U> void ParameterBase::setValue(const U& rhs)
{ return dynamic_cast<Parameter<T>&>(*this).setValue(rhs); }
class Diagram
{
public:
ParameterBase* v;
int type;
};
What I want to be able to do is something like this
if (diagram.getParameter().type == int) {
}
How can I change this implementation so it will allow me to peek what type of Parameter is holding
Thanks for the answers , few more points
I am on C++ 11 so cannot use variant or any
Is there standard way of doing this. All I want is an instance variable of class that can be of multiple types (bounded) and while reading it check what type it is
The Simple Fix
The simple solution to your problem is to add a template function is<T>() to your ParameterBase that is defined in terms of dynamic_cast on a pointer. dynamic_cast with pointers return nullptr on failure, unlike references which will throw a std::bad_cast. For example:
class ParameterBase
{
public:
...
template <typename T>
bool is() const;
};
...
template <typename T>
bool ParameterBase::is() const
{
return dynamic_cast<const Parameter<T>*>(this) != nullptr;
}
The use would be simply:
if (diagram.getParameter().is<int>()) {
...
}
Note, however, that this whole design is not particularly nice. It has a cyclic dependency between the base and derived in a way that is highly coupled. Additionally it requires ParameterBase to exist as a pointer in order to operate correctly; where value-semantics would be much more coherent (if possible)
It would be better if you can use type-erasure, even if you define Parameter in terms of it (this is what C++17's std::any will do for you). The second answer in your linked question already describes what this may look like.
Type-erased Solution (c++11)
This uses C++11 features like forwarding references, rvalue-references, and unique_ptr -- but the concept can also be applied to earlier C++ versions.
For type-erasure, you would need an interface that encompasses at least these 2 features:
getting a reference to the templated type, and
getting an identifier for the current type.
Since interfaces in C++ can't be virtual, we have to get creative about returning the reference. C++ has void* which can be any kind of pointer. This can be bad if misused (such as casting between the wrong type); but if we know the underlying type, can be perfect. Thankfully here, we know the underlying type.
A quick form of type-erasure could be achieved with the following:
#include <type_traits> // std::decay
#include <utility> // std::forward
#include <typeinfo> // std::type_info, std::bad_cast
#include <memory> // std::unique_ptr
class Parameter
{
private:
// This is the interface we will implement in all instances
struct Interface {
virtual ~Interface() = default;
virtual void* get() = 0;
virtual const std::type_info& type() const = 0;
};
// This is the concrete instantiation of the above interfaces
template <typename T>
struct Concrete : public Interface {
template <typename U>
Concrete(U&& u) : m_value{std::forward<U>(u)} {}
void* get() { return &m_value; }
const std::type_info& type() const { return typeid(T); }
T m_value; // actually holds the value here
};
// This holds onto the interface, and only the interface
std::unique_ptr<Interface> m_interface;
public:
// Constructs a parameter and sets the first interface value
template <typename T>
explicit Parameter(T&& value)
: m_interface{new Concrete<typename std::decay<T>::type>{std::forward<T>(value)}}
{}
Parameter(Parameter&&) = default;
Parameter& operator=(Parameter&&) = default;
// Check if we are the same type by comparing the typeid
template <typename T>
bool is() const {
return typeid(T) == m_interface->type();
}
// Get the underlying value. Always check that we are the correct type first!
template <typename T>
const T& get() const {
// do the error handling ourselves
if (!is<T>()) { throw std::bad_cast{}; }
// cast void* to the underlying T*. We know this is safe
// because of our check above first
return (*static_cast<T*>(m_interface->get()));
}
// Set the underlying value. Always check that we are the correct type first!
template <typename T, typename U>
void set(U&& value) {
// do the error handling ourselves
if (!is<T>()) { throw std::bad_cast{}; }
(*static_cast<T*>(m_interface->get())) = std::forward<U>(value);
}
};
In the above, we take on the burden of detecting the underlying type ourselves -- but we remove the cyclic coupling. We now also have a proper value-type that we can move around like a normal variable, which is really helpful since it allows us to return this object from APIs without worrying about lifetime or ownership.
If copyability is desired as well, the interface can be extended to have a clone() function or something to return copies
Using this object, the code becomes:
if (parameter.is<int>()) {
/* treat parameter as an int */
}
Here's a small working example.
Type-erased Solution (c++17)
If you're looking for a finite set of instantiations, std::variant may be used for this purpose. If the number of possibly underlying types is unbounded, you should look into std::any
In either case, the use of a hierarchy here is superficial (at least in the current example) since the entire type-erasure can be reduced to a singular type with the ability to query the containment. This could be done easily, using std::any as an example:
#include <any> // std::any, std::any_cast
class Parameter
{
public:
// This implementation changes the active type if 'T' is not the same as the stored
// value. If you want to restrict this, you can do error checking here instead.
template <typename T>
void set(const T& value) { m_value = value; }
template <typename T>
const T& get() { return std::any_cast<const T&>(m_value); }
template <typename T>
bool is() const noexcept { return m_value.type() == typeid(T); }
private:
std::any m_value;
};
If you don't want the active member to change, this could be restricted by checking is<T>() first and handling the error somehow.
Querying the active type can be achieved simply by doing:
if (parameter.is<int>()) {
/* treat parameter as an int */
}
If the types are fixed, you can always use std::variant instead using std::has_alternative for the definition of is
Looks like you know in advance all possible types for the parameter (I'm saying that because you have a type field that is expected to be used as an enumeration). If that is the case, you may use the std::variant idiom:
class Diagram
{
public:
std::variant<Parameter<int>, Parameter<std::string>> v;
};
In this case you may use this code to get known the actual type:
switch(v.index()) {
case 0:
// int is used
case 1:
// string is used
}
For sure there are other alternatives. For example, if you have something of a type and you need to test if that is the type expect, you my use std::is_same template:
template <typename T>
class Parameter : public ParameterBase
{
public:
bool isOfTypeInt() const {
return std::is_same_v<T, int>;
}
private:
T value;
};
I am implementing something very similar to std::vector but uses array on the stack instead of memory allocation.
The d-tor calls a function that uses SFINAE.
If value_type is POD the function have empty body.
If value_type is normal class such std::string, the function have a body and destroy all the data properly.
Now, I want to be able to use this new std::vector as constexpr. However even the c-tor is declared constexpr, the code does not compiles because the class have non trivial d-tor.
Here is small part of the code:
template<typename T, std::size_t SIZE>
class SmallVector{
constexpr SmallVector() = default;
~SmallVector(){
destructAll_<value_type>();
}
// ...
template<typename X>
typename std::enable_if<std::is_trivially_destructible<X>::value == true>::type
destructAll_() noexcept{
}
};
Is there anything I can do to make class be constexpr if value_type is POD and keeping functionality for non POD data types.
(Not at the same time of course)
until C+20
Unfortunately, there is no way to enable/disable destructor with SFINAE, nor with future concepts. That is because destructos:
can't be templated
can't have arguments
can't have a return type
What you can do is specialize whole class, or better yet, create a base class that contains only the construct/destruct and basic access and specialize that.
template <class T, class Enable = void>
struct X {
~X() {}
};
template <class T>
struct X<T, std::enable_if_t<std::is_pod<T>::value>> {
};
static_assert(std::is_trivially_destructible<X<int>>::value);
static_assert(!std::is_trivially_destructible<X<std::vector<int>>>::value);
C++ 20
As far as I can tell you can constraint a destructor and get exactly what you want in a very simple and elegant solution:
template<typename T, std::size_t SIZE>
class SmallVector{
public:
constexpr SmallVector() = default;
~SmallVector() requires std::is_trivially_destructible_v<T> = default;
~SmallVector()
{
}
};
static_assert(std::is_trivially_destructible_v<SmallVector<int, 4>>);
static_assert(!std::is_trivially_destructible_v<SmallVector<std::string, 4>>);
However this is a brand new feature and there have been some changes lately (e.g. see Disable non-templated methods with concepts) and the compiler support is still sketchy. gcc compiles this just fine, while clang is confused by the fact that there are two definitions of the destructor godbolt
The example of if constexpr in destructor. (C++17 required)
template<typename Tp, typename TLock>
struct LockedPtr {
private:
Tp *m_ptr;
TLock *m_lk;
void prelock(std::mutex *mtx) { mtx->lock(); }
void prelock(std::atomic_flag *atom) { while(atom->test_and_set(std::memory_order_acquire)); }
public:
LockedPtr(Tp *ptr, TLock *mtx)
: m_ptr(ptr), m_lk(mtx) {
prelock(mtx);
}
~LockedPtr() {
if constexpr (std::is_same_v<TLock, std::mutex>)
((std::mutex *)m_lk)->unlock();
if constexpr (std::is_same_v<TLock, std::atomic_flag>)
((std::atomic_flag *)m_lk)->clear(std::memory_order_release);
}
};
These code is the part of RAII locked smart pointer, to adopt to normal std::mutex and spinlock by std::atomic_flag.
Using function overload to match different type in constructor.
Match type by if constexpr and make something unconvertable to pointer in destructor.
I want to change default_deleter for std::unique_ptr. This is quite easy to achieve, but there is one inconvenient - I have to declare variables using 2 template parameters instead of one, something like this:
std::unique_ptr<MyType, MyDeleter<MyType>> myVar;
As you may see the declaration is long and I have a feeling I can use a shorter version, but I don't know how:)
Is it possible to declare some kind of MyUniquePtr<T> that will be the same as std::unique_ptr<T, MyDeleter<T>>?
EDIT: Matthieu M. already answered, but unfortunately I can't use this feature in Visual Studio as it's not implemented. Is there other way to have this behavior?
Actually it is, using template aliases:
template <typename T>
using MyUniquePtr = std::unique_ptr<T, MyDeleter<T>>;
If your compiler doesn't do template aliases yet, here's the C++03 idiom:
template <typename T>
struct MyUniquePtr {
typedef std::unique_ptr<T, MyDeleter<T> > type;
};
MyUniquePtr<MyType>::type var;
The setup is uglier, but the resulting usage is almost as short: you just need to add ::type.
Does your deleter need to be templated on the type of the object being deleted, or is it sufficient for the function call operator to be templated on the type of object being deleted?
Instead of:
template<typename T>
struct MyDeleter
{
void operator()(T* p) const { /* ... */ }
};
Can you write:
struct MyDeleter
{
template<typename T>
void operator()(T* p) const { /* ... */ }
};
This, of course, depends on what state MyDeleter has to maintain.
Another way conforming to c++03 is a subclass, which unfortunately requires you to reproduce the constructors. (This can be done easier, if your compiler supports variadic template arguments, which may be the case for current MSVC.)
template <class T>
class MyUniquePtr : public std::unique_ptr< T, MyDeleter<T> > {
public:
MyUniquePtr(args...) : std::unique_ptr< T, MyDeleter<T> >(args...) { }
};
You might want to consider writing your own version of a make_unique style function instead specialized for your custom allocation / deletion strategy. This also has the advantage that you can perform any specialized resource acquisition / allocation in an exception safe way. You can then declare your unique_ptr as auto and let type deduction work for you.
I'm trying to write a smart pointer wrapper (contains a boost shared_ptr or scoped_ptr or another smart pointer wrapper); each wrapper type injects a bit of extra functionality (eg. logging usage, lazy init, verifying correct construction/destruction order, etc) but I want them to be as invisible as possible to the user (such that I could swap in/out wrappers simply by changing a single typedef, and possibly some constructor code, but none of the usage code).
Normal usage is trivial:
template<typename T>
class some_smart_ptr_wrapper
{
public:
typedef typename T::value_type value_type;
...
value_type* get() { /*do something magic*/ return m_ptr.get(); }
const value_type* get() const { /*do something magic*/ return m_ptr.get(); }
// repeat for operator->, operator*, and other desired methods
private:
T m_ptr;
};
typedef some_smart_ptr_wrapper< boost::shared_ptr<int> > smart_int;
smart_int p;
(Now all other code can use p indistinguishably from a shared_ptr, at least for the defined operations, and I can add extra wrappers just by changing the typedef.)
Multiple wrappers can be used simultaneously simply by nesting them as you'd expect, and only the code that declares (and sometimes initialises) the variable needs to care.
Occasionally though it's useful to be able to get the "basic" shared/scoped_ptr from a wrapper (particularly to pass a shared_ptr as an argument to a function that doesn't need to trigger the functionality added by the wrappers); for a single wrapper layer it's easy:
T& getPtr() { return m_ptr; }
const T& getPtr() const { return m_ptr; }
But this doesn't scale nicely to multiple wrapper layers (the caller has to do p.getPtr().getPtr().getPtr() the correct number of times).
What I'd like to be able to do is to declare getPtr() such that:
if T implements getPtr(), then it returns m_ptr.getPtr() (whatever type that is).
if T does not implement getPtr(), then it returns m_ptr.
it's still available in both const and non-const flavours, as you'd expect.
The net result of which is that a single call to getPtr() from the outside code will "walk up" the chain to the original smart pointer, since that will be the only one that doesn't implement getPtr().
I'm fairly sure that the solution will involve SFINAE and boost::enable_if; I've had a bit of a play towards trying to get something like that to work but haven't had much luck thus far.
Solutions or completely alternate approaches both welcomed; note that I would like it to work in both VC++2008 and GCC (ie. no C++11, sadly).
(1) Declare a special member typename which is unique inside:
template<typename T>
class some_smart_ptr_wrapper
{
public:
typedef T smart_type; // <-- unique name
...
};
(2) Wrap getPtr() inside a template function wrapper:
template<typename T>
class some_smart_ptr_wrapper
{
...
public:
T& getPtr () { return m_ptr; }
typename My_sfinae<T>::RealType& getFinalPtr ()
{ return My_sfinae<T>::getPtr(m_ptr); }
...
};
(3) Where My_sfinae is implemented as usual:
template<typename T>
struct void_ { typedef void type; };
template<typename T, typename = void>
struct My_sfinae {
typedef T RealType;
static T& getPtr (T &p) { return p; }
}; //^^^^^^^^^ business logic!
template<typename T>
struct My_sfinae<T, typename void_<typename T::smart_type>::type> {
typedef typename My_sfinae<typename T::smart_type>::RealType RealType;
static RealType& getPtr (T &p)
{ return My_sfinae<typename T::smart_type>::getPtr(p.getPtr()); }
};
As you can see, My_sfinae removes all your wrappers recursively and finally you are left with the final m_ptr.
Here is the demo.
It is, actually, a simple problem: just use Overloading :)
template <typename T>
boost::scoped_ptr<T>& get_pointer(boost::scoped_ptr<T>& sp) { return sp; }
template <typename T>
boost::shared_ptr<T>& get_pointer(boost::shared_ptr<T>& sp) { return sp; }
// One overload per "wrapper"
template <typename T>
typename get_pointer_type<T>::type& get_pointer(some_wrapper<T>& p) {
return get_pointer(p.getPtr());
}
The trick is then to correctly specialize get_pointer_type for each wrapper.
template <typename T>
struct get_pointer_type { typedef T type; };
template <typename T>
struct get_pointer_type< some_wrapper<T> > {
typedef typename get_pointer_type<T>::type type;
};
The closest thing that comes to my mind is the paper written by Bjarne Stroustrup called Wrapping C++ Member Function Calls.
This paper presents a simple, general, and efficient solution to the old problem of
‘‘wrapping’’ calls to an object in pairs of prefix and suffix code. The solution is also
non-intrusive, applies to existing classes, allows the use of several prefix/suffix pairs, and
can be implemented in 15 simple lines of Standard C++. A robust version of the wrapper
is also presented. The claim of efficiency is backed by measurement.
I have an std::vector-like class that is compiled with Visual C++ 2008. There's a piece in that class where stored elements are moved - either the body is reallocated or an insertion/partial erasure is done. Now some types can just be memmove()d while others need to be copy-constructed at the new location, then destroyed at the original location.
Currently there's a templated function that implements "copy-construct, then destroy" and there's a specialization for each type that can be memmove()d. I'd like to use Visual C++ 2008 support of type traits to simplify that task.
What I want is that for each POD memmove() is selected automatically. I don't mind if some types that can be memmove()d are moved using that templated function, but I can't tolerate the opposite situation - when a datatype that can't be memmove()d is memmove()d.
Looks like __is_pod() intrinsic will do, but MSDN says it returns false for built-in types. So I guess I need to also use __is_class() to first filter out non-classes.
So I though the following will do:
if( !__is_class(T) ) { // not a struct and not a class - built-in type
//memmove()
} else if( __is_pod(T) ) { // is a struct or a class and is a POD
//memmove()
} else { // is a struct or a class and is not a POD
//DefaultMoveViaCopy()
}
Will my solution work okay?
Using boost's enable_if:
template <typename T, class Enabler = void>
struct SmartCopy
{
static void apply(const T& obj, T* dest)
{
// Generic copy...
}
}
template <typename T>
struct SmartCopy<T, typename boost::enable_if_c<__is_pod(T) || !__is_class(T)>::type >
{
static void apply(const T& obj, T* dest)
{
// memmove version...
}
}
template <typename T>
void smart_move(const T& obj, T* dest)
{
SmartCopy<T>::apply(obj, dest);
}