C++ Declare Aligned Storage for Placement-New - c++

I've created some templates in order to create aligned-storage capable of being used for placement-new:
template<typename T, typename... U>
constexpr size_t max_alignof()
{
if constexpr (sizeof...(U))
return std::max(alignof(T), max_alignof<U...>());
else
return alignof(T);
}
template<typename T, typename... U>
constexpr size_t max_sizeof()
{
if constexpr (sizeof...(U))
return std::max(sizeof(T), max_sizeof<U...>());
else
return sizeof(T);
}
// This isn't allowed by the standard, but illustrates my goal
template <typename... T>
using aligned_buffer_t = alignas(max_alignof<T...>()) char[max_sizeof<T...>()];
// Types A, B are classes that I want to placement-new
aligned_buffer_t<A, B> buffer;
A* = new (&buffer[0]) A();
A->~A();
B* = new (&buffer[0]) B();
B->~B();
How can I accomplish the above, without having to re-type the template parameters to aligned_buffer_t? The best solution I could come up with to accomplish this was the following macro:
#define ALIGNED_BUFFER_T(VAR, ...)\
alignas(max_alignof<__VA_ARGS__>()) char VAR[max_sizeof<__VA_ARGS__>()]
ALIGNED_BUFFER_T(buffer, A, B);
Is the above possible without using macros, and without using the deprecated std::aligned_storage? The reason I am interested is because one of the class lists is auto-generated, so the code I tried to write was:
aligned_buffer_t<
#include "GeneratedClassList.hpp"
> buffer;
I couldn't figure out any syntax using macros that would enable such a construct.

As pointed out by ALX23z, my proposed approach was just a roundabout way of reimplementing std::variant. The solution therefore is simply to change the code to:
std::variant<std::monostate, A, B> buffer;
A *a = &buffer.emplace<A>();
// Do stuff with a
B *b = &buffer.emplace<B>();
// Do stuff with b

Related

Function pointer overloading using typedef

As I understand, typedef cannot be used for overloading but what if I need to use some different types as arguments to the function pointer?
How can I make it work with the following functionality?
{
public:
typedef void (*InitFunc)(float x);
typedef void (*InitFunc)(int a, char b); //Needs to be added
virtual void initialize(InitFunc init) = 0;
};
Edit:
I cannot use C++17, so can't use variant
As commented, the easiest way is a union, although not very type safe and C++-y. Here is an example with inheritance, since you commented that you want inheritance.
typedef void (*FloatInit)(float x);
typedef void (*IntCharInit)(int a, char b);
union InitFn {
FloatInit fi;
IntCharInit ici;
};
struct Foo {
void initialize(InitFn) = 0;
};
struct FloatFoo: public Foo {
void initialize(InitFn f) override {
f.fi(42.0f);
}
};
void test(float) {}
// ...
auto x = FloatFoo{};
x.initialize(InitFn{test});
As mentioned by other commenters, you can use std::variant to enhance type safety and get rid of the manual union definition:
typedef void (*FloatInit)(float x);
typedef void (*IntCharInit)(int a, char b);
typedef std::variant<FloatInit, IntCharInit> InitFn;
struct Foo {
void initialize(InitFn) = 0;
};
struct FloatFoo: public Foo {
void initialize(InitFn f) override {
std::get<FloatInit>(f)(42.0f);
}
};
void test(float) {}
// ...
auto x = FloatFoo{};
x.initialize(InitFn{test});
One solution is to create a simple wrapper class template instead, to allow the compiler to automatically generate instantiations as necessary. This is relatively simple if init is always guaranteed to be a non-member function (and by extension, an actual function and not a functor/lambda).
// Quick-and-dirty transparent callable wrapper, to serve as overloadable "type alias".
template<typename>
class InitFunc;
template<typename Ret, typename... Params>
class InitFunc<Ret(*)(Params...)> {
public:
// Supply component types if needed.
// Tuple used for params, for convenience.
using return_type = Ret;
using param_types = std::tuple<Params...>;
using func_type = Ret(Params...);
using func_ptr_type = func_type*;
using func_ref_type = func_type&;
// Create from pointer or reference.
constexpr InitFunc(func_ptr_type p = nullptr) : ptr(p) {}
constexpr InitFunc(func_ref_type r) : ptr(&r) {}
// Transparent invocation.
// Deduces argument types instead of relying on Params, to allow for perfect forwarding.
template<typename... Ts>
constexpr return_type operator()(Ts&&... ts) { return ptr(std::forward<Ts>(ts)...); }
// Convert back to original type if necessary.
operator func_ptr_type() { return ptr; }
operator func_ref_type() { return *ptr; }
private:
// Actual function pointer.
func_ptr_type ptr;
};
// And a nice, clean creator, which can be renamed as necessary.
template<typename Init>
constexpr auto make(Init func) { return InitFunc<Init>(func); }
This creates a nice little wrapper that can easily be optimised out entirely, and will compile as long as C++14 support is available.
Note that you require a C++11 compiler (or variadic templates, rvalue references, perfect forwarding, and constexpr support) at the absolute minimum, and will need to modify make() to have a trailing return type for pre-C++14 compilers. I believe this is compatible with C++11 constexpr, but I'm not 100% sure.
If you want InitFunc to be able to accept pointers/references-to-member-function (including functors and lambdas), you'll need to provide an additional version to isolate it into a non-member "function", and likely bind it to a class instance. It may be worth looking into std::bind() in this case, although I'm not sure if it has any overhead.
In this case, I would suggest splitting the member types off into a base class, to reduce the amount of code you'll need to duplicate.
// Quick-and-dirty transparent callable wrapper, to serve as overloadable "type alias".
template<typename>
class InitFunc;
// Supply component types if needed.
// Tuple used for params, for convenience.
// Using actual function type as a base, similar to std::function.
template<typename Ret, typename... Params>
class InitFunc<Ret(Params...)> {
public:
using return_type = Ret;
using param_types = std::tuple<Params...>;
using func_type = Ret(Params...);
using func_ptr_type = func_type*;
using func_ref_type = func_type&;
};
// Non-member functions.
// As member types are now dependent types, we qualify them and use `typename`.
// Yes, it looks just as silly as you think it does.
template<typename Ret, typename... Params>
class InitFunc<Ret(*)(Params...)> : public InitFunc<Ret(Params...)> {
// Actual function pointer.
typename InitFunc::func_ptr_type ptr;
public:
// Create from pointer or reference.
constexpr InitFunc(typename InitFunc::func_ptr_type p = nullptr) : ptr(p) {}
constexpr InitFunc(typename InitFunc::func_ref_type r) : ptr(&r) {}
// Transparent invocation.
// Deduces argument types instead of relying on Params, to allow for perfect forwarding.
template<typename... Ts>
constexpr typename InitFunc::return_type operator()(Ts&&... ts) { return ptr(std::forward<Ts>(ts)...); }
// Convert back to original type if necessary.
operator typename InitFunc::func_ptr_type() { return ptr; }
operator typename InitFunc::func_ref_type() { return *ptr; }
};
// See ecatmur's http://stackoverflow.com/a/13359520/5386374 for how to accomodate member functions.
// ...
// Non-member function make() is unaffected.
// An overload will likely be needed for member functions.
template<typename Init>
auto make(Init func) { return InitFunc<Init>(func); }
Despite the awkwardness inside our derived specialisation, any code that relies on InitFunc shouldn't (to my knowledge) see any changes to its API; the previous example will work just fine if we swap to this new InitFunc, and be none the wiser after recompilation.
Note that it will change the ABI, though, and thus any code compiled for the simpler InitFunc will need to be recompiled for this version.

How to remove decltype(&MyClass::funct) part by extending the following type traits?

I wanted to have type traits which will help me to get the type of the class
from a member function pointer. I looked into this answer
and found my half way to the aim.
It looks like this:
#include <iostream>
// example class
struct MyClass {
void funct() { std::cout << "funct has been called....\n"; }
};
// traits
template<typename Class> struct get_class{};
template<typename ReType, typename Class, typename... Args>
struct get_class<ReType(Class::*)(Args...)>
{
using type = Class;
};
template<typename Type> using get_class_t = typename get_class<Type>::type;
int main()
{
get_class_t<decltype(&MyClass::funct)> myObj;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---> this is a lot of typing
myObj.funct();
return 0;
}
But, as shown in the code I need every time to write get_class_t<decltype(&MyClass::funct)>
or in the case of
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
// ^^^^^^^^^^^^^^
which is a lot of decltype()ing. I would like to write instead
class_t<ptr> obj;
or
class_t<&MyClass::funct> myObj;
which is more convenient.
I did the following function, which will return a resulting object of the class
and maybe I could do, want I wanted to.
template<typename Type>
auto helper_function(Type ptr)->get_class_t<Type>
{
return get_class_t<Type>{};
}
template<typename Type>
using class_t = /* decltype(helper_function(Type ptr));*/
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // what could be here?
I do not know how to complete this. My goal is to extend the traits in such a way that I
could create an object like
auto ptr = &MyClass::funct;
class_t<ptr> myObj;
// or
class_t<&MyClass::funct> myObj;
Is there any other way to do this? or should I have to stick with decltype()ing?
As I have tagged, I would like to see whether it possible with C++11?
(Answer archived for future visitors; this solution requires C++17!)
You're really close!
The trick is auto template arguments, and the fact that pointers-to-members can be used as template arguments, like so:
template <auto thing>
using class_t = get_class_t<decltype(thing)>;
int main()
{
class_t<&MyClass::funct> myObj;
myObj.funct();
}
Of course if you can write this then you already know the type so you'd just write MyClass, so that's not very useful.
Sadly you won't be able to make it accept ptr as a template argument, though; you're stuck with get_class_t for that:
int main()
{
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
myObj.funct();
}
(live demo)
In the latter case, a nice type alias can help you a bit:
auto ptr = &MyClass::funct;
using ClassType = get_class_t<decltype(ptr)>;
ClassType myObj;
myObj.funct();
(live demo)
Personally I think this level of verbosity is pretty reasonable.
You can provide a function which will create required object. This is very simple to achieve:
template<typename T, typename ...Args>
auto makeObjectForMethod(T&&, Args&& ...args) -> get_class_t<decltype(&MyClass::funct)>
{
using R = get_class_t<decltype(&MyClass::funct)>;
return R{ std::forward(args)... };
}
int main()
{
auto myObj = makeObjectForMethod(&MyClass::funct);
myObj.funct();
return 0;
}
Works with C++11 and is quite handy:
https://wandbox.org/permlink/usMa3fA0I2HCNJ7M
The only disadvantage that in case of class fields it is not very helpful.

Convenient type-inferring way to reassign `unique_ptr` value with new object

Is there a convenient way to re-assign the value of a unique_ptr with a new owned object, without re-specifying the type?
For instance:
std::unique_ptr<int> foo;
// .... Later, once we actually have a value to store...
foo = std::make_unique<int>(my_cool_value);
Of course int is not too much of an eyesore, but foo::element_type could be long or subject to change after a refactoring.
So, to use type inference, we could do:
foo = std::make_unique<decltype(foo)::element_type>(value);
...But that's pretty hideous (foo::element_type doesn't work because foo can't be used in a constant expression).
Ideally, std::unique_ptr would support a forwarding emplace-like method:
foo.reassign(value);
This would release the old value and, just like std::vector::emplace, construct the new owned object in-place.
....But as far as I can tell, there's nothing more concise than make_unique<decltype(foo)::element_type>.
EDIT: The most concise way to reassign the value for a type that supports operator= is, of course, to use operator=:
*foo = value;`
...But I do not want to rely on the copyability of element_type (for instance, I initially ran into this issue when trying to work with input-file streams).
Stash the arguments (or references thereto) into a proxy object with a templated conversion operator that deduces the target type. Then construct the new object once you have that deduced.
template<class... Args>
struct maker {
template<class T>
operator std::unique_ptr<T>() && {
return make<T>(std::index_sequence_for<Args...>());
}
std::tuple<Args...> args;
private:
template<class T, size_t ... Is>
std::unique_ptr<T> make(std::index_sequence<Is...>) {
return std::make_unique<T>(std::get<Is>(std::move(args))...);
}
};
template<class... Args>
auto maybe_make_unique_eventually(Args&&... args){
return maker<Args&&...>{std::forward_as_tuple(std::forward<Args>(args)...)};
}
It won't be a member function, but a free function could essentially achieve this:
template<typename T, typename D, typename...Args>
void TakeNew(std::unique_ptr<T,D>& up, Args&&... args)
{
up.reset(new T{std::forward<Args>(args)...});
// or use parentheses for consistency with `make_unique`; see comments
}
// usage...
auto foo = std::make_unique<int>(3);
// .... Later...
TakeNew(foo, 5);
(I do not consider this solution ideal.)
#include <memory>
// a class with a long and unweildy name
namespace mary {
namespace poppins {
struct supercalafragalisticexpialadocious
{
};
}
}
int main()
{
// what we don't want to have to do:
auto a = std::make_unique<mary::poppins::supercalafragalisticexpialadocious>();
// so alias the typename
using atrocious = mary::poppins::supercalafragalisticexpialadocious;
// same type with a shorter name
a = std::make_unique<atrocious>();
}
As you have unique ownership, unless the type is not copyable, you may simply do
*foo = value;

Template classes - a couple of questions

I need to create constructor taking two integers as arguments.
From there I need to call method taking these integers by reference. Inside this method I should dynamically convert integers into char* type (array of digits).
At the end of the constructor I should have two char* arrays instead of initial integers.
I kind of have to do it this way because the other class does the same thing but on structures. And save them into the template attributes.
I'm new to c++ language but my first guess was to use templates. I did a little research on the topic and found out it should work.
I'd love to compile the whole thing myself, but the mess with implementing c++ classes in my head produces quite long list of compile errors.
First question - can this be done using templates?
Second question, because I've already written something by myself:
template <class type> class Addition {
type num_a;
type num_b;
void convert(type, type);
public:
Addition(type, type);
}
template <class type> Addition::Addition(type a, type b) {
convert(&a, &b);
num_a = a;
num_b = b;
}
template <class type> Addition::convert(type *a, type *b) {
int temp_a = a, temp_b = b;
a = char[256], b = char[256];
// converting
}
Is this o.k., or did I do something wrong?
Do you have any suggestions about the way I implement classes in c++?
Why can't I initialize attribute with a value, like:
template <class type> class Addition {
type outcome = 0;
}
And if there's no need to use this keyword in c++, how do I do something like this?:
template <class type> Addition::Foo(type a, type b) {
this->a = a; // a = a;
this->b = b; // b = b;
}
Disclaimer: I cannot judge wheter you really need templates for what you are doing. That would depend on the number of different types that you want your Adddition class template to work with. If you will only use it for int, then perhaps this will introduce unnecessary complexity. You can always refactor later (this would be the Agile approach).
Having said that, if you want to use templates, the usual convention is to write T for a template parameter, and to use type for a nested typedef inside a class template. Using typename or class is a matter of taste, but typename stresses the fact that builtin types can also be passed as arguments. Note however that with template-template parameters you would need to write
template<template<typename> class U> SomeClass { /* your definition */ };
^^^^^ // <-- NOT typename here
which stresses the fact that only class templates can be passed as arguments.
There are a few other nitpicks that one could mention about your code that would make it fail to compile (missing return type in convert() and missing semi-colon in class definition):
template <typename T>
class Addition
{
static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
T num_a;
T num_b;
void convert(T const*, T const*); // by T const*, not T*
public:
Addition(T const&, T const&); // by T const&, not T
}; // <-- make sure to end class definitions with a semi-colon!
template <typename T>
Addition::Addition(T const& a, T const& b)
{
convert(&a, &b);
num_a = a;
num_b = b;
}
template <typename T>
void Addition::convert(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
^^^^ // <-- you forgot the return type
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
// converting
}
In C++11 you can even use delegating constructors (supported by latest Visual C++ and of course gcc/Clang) and write
template <typename T>
Addition::Addition(T const& a, T const& b)
:
Addition(&a, &b) // delegate to the other constructor
{}
template <typename T>
Addition::Addition(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
// converting
}
Finally, because template definition have to be in headers anyway, you could even write everything inside the class definition like this:
template <typename T>
class Addition
{
static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
T num_a;
T num_b;
Addition(T const*, T const*) // by T const*, not T*
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N];
// converting
}
public:
Addition(T const&, T const&) // by T const&, not T
:
Addition(&a, &b) // delegate to the other constructor
{}
}; // <-- make sure to end class definitions with a semi-colon!
This saves you from tediously writing both declarations and definitions of all the member functions. For short and sweet classes (which you should strive for anyway) this is the preferred way of writing templates, but for very long definitions you might want to separate the declaration and definition.
Finally, as was explained by #tacp, you really need to use this->a to disambiguate a class data member from a function parameter. For that reason, people often write data members with a trailing underscore or a m_ prefix.
For your latter questions:
template <class type> class Addition {
//type outcome = 0;
//^^^^you have to call default constructor of type
type outcome = type();
}
It is better to use typename for convention, using class is also OK.
template <class type> Addition::Foo(type a, type b) {
this->a = a; // a = a;
this->b = b; // b = b;
}
If the passed parameter and member has the same name, you need to use this. You cannot do
a =a;
b =b;
since a,b are in local scope, but this->a means class member a.
Since you always want to convert integers to char array, I don't think you really need templates. Unless you would like convert double, float and other types into char* also in the future. I have not looked all the issues, so there may be others remain.

Any way to let the use of function pointers as template arguments easier?

I can use function pointer as template argument as the following
template<class R, class T, R (*Fun)(T)>
class MyClass;
Any way to make it is easy as
MyClass<&MyFun> a;
Here is a horrible answer, but I cannot think of a better one.
template<typename R, typename Arg, R(*Fun)(Arg)>
class MyClass {};
template<typename R, typename Arg>
struct MyClassHelper {
template<R(*Fun)(Arg)>
struct Class {
typedef MyClass<R, Arg, Fun> type;
};
};
template<typename R, typename Arg>
MyClassHelper<R, Arg> GetMyClass(R(*Fun)(Arg)); // no impl
void MyFun(int) {}
int main() {
typedef decltype( GetMyClass(&MyFun) ) A;
typedef A::Class<&MyFun> B;
typedef B::type a;
// or, in one line:
decltype( GetMyClass(&MyFun) )::Class<&MyFun>::type b;
}
which is ugly as sin. But at least it extracts the argument types of MyFun without repeating them...
It's not possible exactly as in the question, but yes it's possible if you flex your design a little bit. Let's take an example:
Suppose you have below function:
int foo (int i) { return i; }
Now you want to write:
MyClass<&foo> a; // instead of `Myclass<int, int, &foo> a;
Here how you will achieve it. First change the simple function:
int foo (int i) { return i; }
to encapsulated function object:
struct foo { // <--- function name here
int operator () (int i) { return i; } // <--- function body here
};
Both are almost same (in the case of function object an extra this pointer is passed which doesn't happen in the free function case):
int x = foo(2); // 1st case
int x = foo_(2); // 2nd case where `foo_` is an object of `struct foo`
Now you can use simply as you want!
template<class Func>
class MyClass {...}
MyClass<foo> a;
Here is a working demo.
There's already std::ptr_fun. With C++11, you can use it as
auto a = std::ptr_fun(&MyFun);
Update:
As the other attempts, and non attempts BTW, have shown, isn't it possible with your kind of template, least of all "as easy as" ;-). What you can do however, is sort of reimplement the existing standard template function pattern (std::ptr_fun, std::make_pair and the like) to return the desired type, if your main goal is "as easy as".