How to use Objective-C sources' ExplicitInit class? - c++

In the Objc source code, I found the following code. What is the meaning of this code and how to understand it?
objc/Project Headers/DenseMapExtras.h line:38
template <typename Type>
class ExplicitInit {
alignas(Type) uint8_t _storage[sizeof(Type)];
public:
template <typename... Ts>
void init(Ts &&... Args) {
new (_storage) Type(std::forward<Ts>(Args)...);
}
Type &get() {
return *reinterpret_cast<Type *>(_storage);
}
};
Below is my test code:
class MyC{
public:
long l1;
long l2;
MyC(long _l1, long _l2){
l1 = _l1;
l2 = _l2;
}
};
int main(){
MyExplicitInit<MyC> e1 {};
e1.init();
return 0;
}
The compiler prompts the following error:

In the Objc source code, I found the following code. What is the
meaning of this code and how to understand it?
To me it looks like a kind-of-factory which can be used as an alternative to the Construct On First Use Idiom. An instantiated class here represents a storage for an instance you can initialise and request when needed. As far as I understand it's not supposed to be used for local variables (it doesn't make much sense, despite being technically possible) and this is also suggested by the comments of code section with the said class template:
// We cannot use a C++ static initializer to initialize certain globals because
// libc calls us before our C++ initializers run. We also don't want a global
// pointer to some globals because of the extra indirection.
//
// ExplicitInit / LazyInit wrap doing it the hard way
For the error you are experiencing:
No matching operator new function for non-allocating placement new expression;
include <new>
Assuming that you just added that piece of code somewhere in your own sources, the problem here is that you didn't include the <new> header. As simple as that - the error just says that you need to add #include <new> since so-called placement new is not part of the "default" C++, it's an overloaded operator declared in this header.
Second, your init function expects arguments that matches one of the existing (non-aggregate) constructors of the given class, so you are expected to pass arguments which are either match the constructor parameters or can be implicitly converted to them: e1.init(1l, 2l)
A complete example looks something like this:
#include <_types/_uint8_t.h>
#include <new>
namespace objc {
template <typename Type>
class ExplicitInit {
alignas(Type) uint8_t _storage[sizeof(Type)];
public:
template <typename... Ts>
void init(Ts &&... Args) {
new (_storage) Type(std::forward<Ts>(Args)...);
}
Type &get() {
return *reinterpret_cast<Type *>(_storage);
}
};
};
struct sample_struct {
long l1, l2;
sample_struct(long _l1, long _l2): l1{_l1}, l2{_l2} {}
};
sample_struct& getInstance(bool should_init = false) {
static objc::ExplicitInit<sample_struct> factory;
if (should_init) {
factory.init(1l, 2l);
}
return factory.get();
}

Related

How to alias a template function inside a template class

I have a need to implement 2 functions inside a templated class, where both functions do similar things, but not everything is the same. My proposed solution was to use if constexpr on a single template function, and then have an alias for each function:
template <typename T>
class MyClass
{
private:
template <bool test>
void TestFunc()
{
if constexpr(test)
{
// Do something
}
else
{
// Do other stuff
}
}
public:
?????? TestTrue = TestFunc<true>;
?????? TestFalse = TestFunc<false>;
}
I'm trying to figure out what should go where the question marks are, so far using, auto and const auto have not worked. I want the user to be able to call TestTrue() and TestFalse() directly from an object of the class directly.
You could do:
void TestTrue() { TestFunc<true>(); }
void TestFalse() { TestFunc<false>(); }
I don't think there's a better way.
For completeness, here's the ugly way.
As mentioned in the comments, TestFunc is a member function, not a type, so if you want to reference an explicit specialization of it, you'll need to use a member function pointer. In our case, these will be pointers of the following type.
using MemberTestFunction = void (MyClass::*)();
We can then acquire pointers to the true and false specialization of TestFunc like so:
template <typename T>
class MyClass
{
// ...
constexpr static MemberTestFunction TestTrue = &MyClass::TestFunc<true>;
constexpr static MemberTestFunction TestFalse = &MyClass::TestFunc<false>;
};
If you're not familiar with pointers to member functions, the syntax for calling TestTrue and TestFalse may look rather bizarre. If you're inside a member function, you can invoke these functions either by using the ->* operator, or by using std::invoke (C++17) from <functional>:
template <typename T>
class MyClass
{
// ...
void foo() {
// Direct call with pointer.
(this->*TestTrue)();
// Call using std::invoke.
std::invoke(TestTrue, this);
}
};
Alternatively, outside of MyClass, these calls would look like the following.
MyClass<nullptr_t> x;
// Using type deducation.
(x.*decltype(x)::TestTrue)();
// Using fully qualified name.
(x.*MyClass<nullptr_t>::TestTrue)();
// Using std::invoke (with type deducation).
std::invoke(decltype(x)::TestTrue, x);
It goes without saying this this is a needlessly obscure way of accomplishing any otherwise simple task. I would not advocate using this technique over creating new functions (as HolyBlackCat suggested) or simply naming TestFunc<true>() and TestFunc<false>() explicitly at the call site.
Transform function TestFunc to functor:
#include <iostream>
template <typename T>
class MyClass
{
private:
template <bool test>
struct TestFunc
{
void operator()() {
if constexpr(test)
{
std::cout << "TestTrue\n";
}
else
{
std::cout << "TestFalse\n";
}
}
};
public:
TestFunc<true> TestTrue;
TestFunc<false> TestFalse;
};
int main()
{
MyClass<int> myClass;
myClass.TestTrue();
myClass.TestFalse();
}

Constexpr constructible function object

I have a question somewhat similar to this one, but for a more limited case which I believe should be possible somehow: I want to construct a static constexpr array of function calls from a number of lambdas, each sharing the same signature. The static and constexpr part is important here since I'm on an embedded system, where I want to make sure such tables end up in Flash.
So basically what I want to do is
#include<vector>
#include<functional>
#include<variant>
using params_t = std::vector<std::variant<int, float /*maybe others*/ >>;
struct command_t {
using callable_t = std::function<void(params_t)>;
const callable_t func;
//other members..
};
class AClass {
template<typename func_t>
constexpr static command_t::callable_t make_callable(func_t fun) {
return [fun](params_t params){/*construct a call to fun using params and template magic*/};
}
static void mycommand();
static void mycommand2(int i);
//The following fails:
///"error: in-class initialization of static data member 'const command_t AClass::commands [2]' of non-literal type"
static constexpr command_t commands[2] = {command_t{make_callable(mycommand)},
command_t{make_callable(mycommand2)}};
};
On coliru
Note that the type erasure here is quite limited, since the signature of the lambda varies only by the signature of the capture of fun. The function call obviously doesn't (and cannot) need to be constexpr, only the construction.
So basically my question is can I somehow make the commands array static constexpr, either somehow using std::function, or something like inplace_function, or perhaps by spinning my own code for type-erasing the lambda in this specific case?
In general, this is not possible since the capture of a lambda can get arbitrary large and hence, at some point we need a heap allocation which then kills any hopes of constexpr pre-C++20 (and I don't think C++20 will help much for this case, either).
But you only want to capture a function pointer if I see this right and that we can do:
#include <vector>
#include<variant>
using params_t = std::vector<std::variant<int, float /*maybe others*/ >>;
struct command_t {
using callable_t = void (*)(std::vector<params_t>);
const callable_t func;
//other members..
};
template<auto f>
void wrap(std::vector<params_t>){
// make this dependent of f, maybe use function_traits for fancy stuff
}
class AClass {
static void mycommand();
static void mycommand2(int i);
static constexpr command_t commands[2] = {wrap<mycommand>, wrap<mycommand2>};
};
int main() {
}
Thanks to xskxzr for valuable suggestions.
Since mycommanN have different signatures and you need to capture them, I don't see a way to have a constexpr vector. Maybe someone can come up with a better design.
I have a solution: use std::tuple. But I don't really like as it is really cumbersome to work with tuple as a container. For instance iterating over it is ... let's say not a walk in the park. Anyway, here it is in case it does help:
using params_t = std::vector<std::variant<int, float /*maybe others*/>>;
// I needed to lift this out of AClass because of ... complicated reasons
// (short version: when both are AClass members
// the return type of `make_command` is not resolved in the init of `commands`
// because both are static, `commands` is not a template and `make_command` is a template
// tbh I don't know exactly what is happening. It's one of those dark corners of C++)
template <class RealFunc>
static constexpr auto make_command(RealFunc real_func) {
return [real_func](params_t params) { /*magic*/ };
}
struct AClass {
static void mycommand();
static void mycommand2(int i);
static constexpr std::tuple commands{make_command(mycommand),
make_command(mycommand2)};
};
// usage
auto test() {
constexpr auto command0 = std::get<0>(AClass::commands<>);
params_t params0 = {};
return command0(command0);
}

template overload not found

I'm trying to understand why in the following code the assertion fails.
// file dconvert.h
struct A{};
struct B{int n;};
struct C{double cc;};
template<class FromStruct, class ToStruct>
void dconvert(FromStruct from, ToStruct to)
{
struct Placeholder {FromStruct f;};
static_assert(std::is_same<Placeholder, FromStruct>::value, "CONVERSION NOT DEFINED");
}
template<class FromStruct>
void dconvert(FromStruct from,
int to)
{
}
template<class FromStruct>
void dconvert(FromStruct from,
C to)
{
dconvert<FromStruct,int>(from, 5);
}
// file main.cpp
#include <dconvert.h>
int main()
{
::dconvert(3,1); // ok
C c;
::dconvert(3,c); // static assertion fails!
}
The main dconvert function is thought to assert if no other explicit conversion function is implemented.
What I don't understand is why the dconvert function overload is not being seen.
If I remove the lines:
C c;
::dconvert(3,c);
or also if I keep the above ones and I remove
dconvert<FromStruct,int>(from, 5);
no assertion is thrown
This is because in:
template<class FromStruct>
void dconvert(FromStruct from,
C to)
you do this:
dconvert<FromStruct,int>(from, 5);
thus explicitly demanding to instantiate the first template (as it is the only one that has two template parameters) method. If you were to remove this demand, e.g. by allowing template type deduction to happen by leaving it:
dconvert(from, 5);
the code would compile without a problem.
Tested on clang6.0.

Function template parameter

I ran into the following code that defines a function template in a class:
#include <cstdint>
class foo {
public:
enum class magic_type : std::uint32_t {
START = 0,
BLUE = 0xFF000001,
RED,
};
struct header_t {
uint32_t version;
magic_type magic;
};
template <typename T>
static bool is_of_type(header_t *h)
{
return (h->magic == T::magic_type);
}
foo(uint32_t ver, foo::magic_type mag)
{
header.version = ver;
header.magic = mag;
}
header_t header;
};
I am finding the implementation of 'is_of_type` confusing. The code as is compiles, so syntactically must be correct. However, this method is not invoked from any other part of the program, so I am not sure what the intent of the function is (lack of documentation). I figured there could be two interpretation of the function:
Return true/false based on the magic type of an object and the specific enum type passed as the function template parameter.
E.g. An invocation of the method would be:
foo bar(1.2, foo::magic_type::BLUE);
bool temp = bar.is_of_type<foo::magic_type::BLUE>(&(bar.header));
However, in the above case, I am not really passing a type (as in an int, or char, etc). Right? The code does not compile.
Return true/false if the magic type is a valid enum.
In this case, I am assuming the function does not need to be templated, and could be re-written as:
static bool is_of_type(header_t *h)
{
return (h->magic == foo::magic_type);
}
E.g. of an invocation:
foo bar(1.2, foo::magic_type::BLUE);
bool temp = bar.is_of_type(&(bar.header));
Again, getting compile error. I tried using "typename", but my attempts were futile.
Can someone please help me with proper implementation of is_of_type for the above two cases and an invocation example.
The invocation would be with an explicitly specified type, which has a nested static member called magic_type.
For instance, it could be called as follows:
struct test {
static foo::magic_type const magic_type;
};
foo::magic_type const test::magic_type = 42;
foo bar{1, foo::magic_type::BLUE};
bar.is_of_type<test>(bar.header);
The fact that magic_type is used twice, once for an enum class and once for a static variable, is very confusing though.

Uses of pointers non-type template parameters?

Has anyone ever used pointers/references/pointer-to-member (non-type) template parameters?
I'm not aware of any (sane/real-world) scenario in which that C++ feature should be used as a best-practice.
Demonstation of the feature (for pointers):
template <int* Pointer> struct SomeStruct {};
int someGlobal = 5;
SomeStruct<&someGlobal> someStruct; // legal c++ code, what's the use?
Any enlightenment will be much appreciated!
Pointer-to-function:
Pointer-to-member-function and pointer-to-function non-type parameters are really useful for some delegates. It allows you to make really fast delegates.
Ex:
#include <iostream>
struct CallIntDelegate
{
virtual void operator()(int i) const = 0;
};
template<typename O, void (O::*func)(int)>
struct IntCaller : public CallIntDelegate
{
IntCaller(O* obj) : object(obj) {}
void operator()(int i) const
{
// This line can easily optimized by the compiler
// in object->func(i) (= normal function call, not pointer-to-member call)
// Pointer-to-member calls are slower than regular function calls
(object->*func)(i);
}
private:
O* object;
};
void set(const CallIntDelegate& setValue)
{
setValue(42);
}
class test
{
public:
void printAnswer(int i)
{
std::cout << "The answer is " << 2 * i << "\n";
}
};
int main()
{
test obj;
set(IntCaller<test,&test::printAnswer>(&obj));
}
Live example here.
Pointer-to-data:
You can use such non-type parameters to extend the visibility of a variable.
For example, if you were coding a reflexion library (which might very useful for scripting), using a macro to let the user declare his classes for the library, you might want to store all data in a complex structure (which may change over time), and want some handle to use it.
Example:
#include <iostream>
#include <memory>
struct complex_struct
{
void (*doSmth)();
};
struct complex_struct_handle
{
// functions
virtual void doSmth() = 0;
};
template<complex_struct* S>
struct csh_imp : public complex_struct_handle
{
// implement function using S
void doSmth()
{
// Optimization: simple pointer-to-member call,
// instead of:
// retrieve pointer-to-member, then call it.
// And I think it can even be more optimized by the compiler.
S->doSmth();
}
};
class test
{
public:
/* This function is generated by some macros
The static variable is not made at class scope
because the initialization of static class variables
have to be done at namespace scope.
IE:
class blah
{
SOME_MACRO(params)
};
instead of:
class blah
{
SOME_MACRO1(params)
};
SOME_MACRO2(blah,other_params);
The pointer-to-data template parameter allows the variable
to be used outside of the function.
*/
std::auto_ptr<complex_struct_handle> getHandle() const
{
static complex_struct myStruct = { &test::print };
return std::auto_ptr<complex_struct_handle>(new csh_imp<&myStruct>());
}
static void print()
{
std::cout << "print 42!\n";
}
};
int main()
{
test obj;
obj.getHandle()->doSmth();
}
Sorry for the auto_ptr, shared_ptr is available neither on Codepad nor Ideone.
Live example.
The case for a pointer to member is substantially different from pointers to data or references.
Pointer to members as template parameters can be useful if you want to specify a member function to call (or a data member to access) but you don't want to put the objects in a specific hierarchy (otherwise a virtual method is normally enough).
For example:
#include <stdio.h>
struct Button
{
virtual ~Button() {}
virtual void click() = 0;
};
template<class Receiver, void (Receiver::*action)()>
struct GuiButton : Button
{
Receiver *receiver;
GuiButton(Receiver *receiver) : receiver(receiver) { }
void click() { (receiver->*action)(); }
};
// Note that Foo knows nothing about the gui library
struct Foo
{
void Action1() { puts("Action 1\n"); }
};
int main()
{
Foo foo;
Button *btn = new GuiButton<Foo, &Foo::Action1>(&foo);
btn->click();
return 0;
}
Pointers or references to global objects can be useful if you don't want to pay an extra runtime price for the access because the template instantiation will access the specified object using a constant (load-time resolved) address and not an indirect access like it would happen using a regular pointer or reference.
The price to pay is however a new template instantiation for each object and indeed it's hard to think to a real world case in which this could be useful.
The Performance TR has a few example where non-type templates are used to abstract how the hardware is accessed (the hardware stuff starts at page 90; uses of pointers as template arguments are, e.g., on page 113). For example, memory mapped I/O registered would use a fixed pointer to the hardware area. Although I haven't ever used it myself (I only showed Jan Kristofferson how to do it) I'm pretty sure that it is used for development of some embedded devices.
It is common to use pointer template arguments to leverage SFINAE. This is especially useful if you have two similar overloads which you couldn't use std::enable_if default arguments for, as they would cause a redefinition error.
This code would cause a redefinition error:
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void foo (T x)
{
cout << "integral";
}
template <typename T, typename = std::enable_if_t<std::is_floating_point<T>::value>>
void foo (T x)
{
cout << "floating";
}
But this code, which utilises the fact that valid std::enable_if_t constructs collapse to void by default, is fine:
// This will become void* = nullptr
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
void foo (T x)
{
cout << "integral";
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
void foo (T x)
{
cout << "floating";
}
Occasionally you need to supply a callback function having a particular signature as a function pointer (e.g. void (*)(int)), but the function you want to supply takes different (though compatible) parameters (e.g. double my_callback(double x)), so you can't pass its address directly. In addition, you might want to do some work before and after calling the function.
It's easy enough to write a class template that tucks away the function pointer and then calls it from inside its operator()() or some other member function, but this doesn't provide a way to extract a regular function pointer, since the entity being called still requires the this pointer to find the callback function.
You can solve this problem in an elegant and typesafe way by building an adaptor that, given an input function, produces a customised static member function (which, like a regular function and unlike a non-static member function, can have its address taken and used for a function pointer). A function-pointer template parameter is needed to embed knowledge of the callback function into the static member function. The technique is demonstrated here.