Combining 'using' and 'reinterpret_cast' - c++11

I have a list of functions that are put in a table for lookup for an interpreter. I cast each function to void (*) () as follows:
using vptr = void (*) (); // cast to a function that takes no args, and returns no result
struct function date_funs[] =
{
{C_FN3, X_A3, "III", (vptr) do_hms_to_time, "hms_to_time"},
...
This works, and does exactly what I want. I wonder if there was another way of expressing it, like:
using vptr = reinterpret_cast<void(*) ()>;
The C++ compiler complains of a syntax error, though. Is there any way I can fix this, or should I just use the first form of vptr that I devised?

No.
using (in this context) defines a type alias. In your attempt, you are not giving a type, but have a partial expression, which is a syntax error.
To shorten usages, e.g. reinterpret_cast<void(*) ()>(do_hms_to_time), you could introduce a function as well as the using.
using vptr = void (*) ();
template <typename Func>
constexpr vptr to_vptr(Func && func)
{ return reinterpret_cast<vptr>(func); }
and use it
{C_FN3, X_A3, "III", to_vptr(do_hms_to_time), "hms_to_time"},

Related

How to call a class function which only argument is &

Here's my code:
class Patient {
public:
const int patientId;
const PatientKind kind;
const bool hasInsurance;
std::vector<ProcedureKind> procedures;
Patient(int, PatientKind, bool);
bool addProcedure(const ProcedureKind procedure);
double billing();
virtual double liability() = 0;
};
class Hospital {
public:
Patient &addPatient(const PatientInfo &);
};`
I don't know how to write:
Patient &Hospital::addPatient(const PatientInfo &)
{
}
Whatever I try to return or pass as argument gives me an error... Also, I don't understand what is this function expecting as an argument with just &?
Any kind of help / insight will be appreciated :D
Seems like you're trying to implement a header definition someone else wrote. That & means that the function expects a reference to an instance of PatientInfo. In the implementation, the only thing you have to do is to give the parameter a name like so:
Patient& addPatient(const PatientInfo& info)
{
// do whatever you need with 'info'
}
You can read more about c++ function declaration and implementation in any basic c++ text.

C++11 forwarding Template template parameter does not work

I used template template parameter as follows:
/* [1]: Definition containing a template template parameter */
template <typename T, template<class> class Kernel>
void ForEach(Kernel<T> kernel, T * pSrc, int elementCount) {
//....
}
/* [2]: Definition of a helper struct */
template <typename T> struct KernelStd {
//...
};
/* [3]: Use the previous definitions */
float arr1[5] = {1,2,3,4,5};
//The following two calls to ForEach do successfully compile
ForEach(KernelStd<float>(), arr1, 5); //USE1
ForEach<float>(KernelStd<float>(), arr1, 5); //USE2
/* [4]: Definition of a helper function */
template <typename F, typename ...Args>
void forwarder(F func1, Args && ...args) {
//...
func1(std::forward<Args>(args)...);
}
//But the following callS do not compile.
forwarder(ForEach, KernelStd<float>(), arr1, 5); //USE3
forwarder(ForEach<float>, KernelStd<float>(), arr1, 5); //USE4
I am using VS2013 update 5 and I get the following error:
error C2783: 'void ForEach(Kernel<T>,T *,int)' : could not deduce
template argument for 'Kernel'
Any help will be appreciated.
forwarder is a function, so its first argument must be an entity (object or function) of type F.
ForEach is neither a function nor an object, it's a template. You therefore cannot pass ForEach to forwarder.
ForEach<float> does not pass enough template arguments to fully identify a function instantiated from the ForEach template. You can get away with it when calling the function template because of template argument deduction. But in the context of forwarder, the type F is supposed to be deduced from the first argument, so you have a bit of a chicken-and-egg problem.
If you want to use forwarder, you must supply it with an actual function, not with a template. So you'd have to do this:
forwarder(ForEach<float, KernelStd>, KernelStd<float>(), arr1, 5);
ForEach<float, KernelStd> contains all template arguments and it therefore designates a function (instantiated from a template).

Unique_ptr of unique_ptr in decorator pattern

Given a decorator class with standard decorator CTOR
explicit TheDecorator(std::unique_ptr<BaseClass> &&p_rrBase);
I want to create a member variable that is a unique ptr of such a decorator. I thus tried
unique_ptr<DerivedClass> spToDeco(make_unique<DerivedClass>() ); // class to decorate
m_spDecoration = make_unique<TheDecorator>( move(spToDeco) ); // unique ptr of decorator
Using VS 2010 and Scott Meyers implentation of make_unique (without variadic templates, implementing both a version with zero and one argument(s) instead), I get the error
error C2780: _Ty &&std::forward(...): expects 1 argument -- 0 provided
which I understand, as "TheDecorator" expects the argument to forward. But where the heck do I have to code it into, how do I form the syntax correctly? Am I supposed to include a move in the <> brackets? Thanks a lot for help!
Make_Unique:
namespace std
{
template<typename T>
std::unique_ptr<T> make_unique()
{
return std::unique_ptr<T>( new T() );
}
template<typename T, typename Ts>
std::unique_ptr<T> make_unique(Ts&& params)
{
return std::unique_ptr<T>( new T(std::forward<Ts>()) );
}
}
EDIT 2: SOLVED already, it must read
template<typename T, typename Ts>
std::unique_ptr<T> make_unique(Ts&& params)
{
return std::unique_ptr<T>( new T(std::forward<Ts>(params)) );
}

Enum values as parameter default values in Haxe

Is there a way to use enum default parameters in Haxe? I get this error:
Parameter default value should be constant
enum AnEnum {
A;
B;
C;
}
class Test {
static function main() {
Test.enumNotWorking();
}
static function enumNotWorking(e:AnEnum = AnEnum.A){}
}
Try Haxe link.
Update: this feature has been added in Haxe 4. The code example from the question now compiles as-is with a regular enum.
Previously, this was only possible if you're willing to use enum abstracts (enums at compile time, but a different type at runtime):
#:enum
abstract AnEnum(Int)
{
var A = 1;
var B = 2;
var C = 3;
}
class Test3
{
static function main()
{
nowItWorks();
}
static function nowItWorks(param = AnEnum.A)
{
trace(param);
}
}
There's nothing special about the values I chose, and you could choose another type (string, or a more complex type) if it better suits your use case. You can treat these just like regular enums (for switch statements, etc.) but note that when you trace it at runtime, you'll get "1", not "A".
More information: http://haxe.org/manual/types-abstract-enum.html
Sadly enums can't be used as default values, because in Haxe enums aren't always constant.
This piece of trivia was on the old website but apparently hasn't made it into the new manual yet:
http://old.haxe.org/ref/enums#using-enums-as-default-value-for-parameters
The workaround is to check for a null value at the start of your function:
static function enumNotWorking(?e:AnEnum){
if (e==null) e=AnEnum.A;
}
Alternatively, an Enum Abstract might work for your case.

unique_ptr upcast in return

I have this function that's supposed to generate different derived objs and return as a unique_ptr<base>:
class base {}; // contains pure functions.
class derived1 {}; // reifies that pure iface.
class derived2 {}; // reifies that pure iface.
unique_ptr<base> factory::load(int param)
{
switch (param)
{
case PARAM_MAIN:
return new derived1();
// return std::move(new derived1());
case PARAM_2:
return new derived2();
case ...:
return new derived...();
}
}
there's no way I can get this thing going, even using the std::move. (Also used dynamic_cast, but maybe did it wrong).
This is the error I get: (gcc (GCC) 4.8.1 20130725 (prerelease) on ArchLinux)
could not convert '(std::shared_ptr<base::model>((*(const std::shared_ptr<base::model>*)(& associatedModel))), (operator new(48ul), (<statement>, ((derived1*)<anonymous>))))' from 'derived1*' to 'std::unique_ptr<base>'
associatedModel));
I hope I've been clear about what I wanna do.
How do I do it? Thanks.
You can either do unique_ptr<derived1>(new derived1()); or even better (with C++14) use std::make_unique.
using namespace std;
class base {}; // contains pure functions.
class derived1 {}; // reifies that pure iface.
class derived2 {}; // reifies that pure iface.
unique_ptr<base> factory::load(int param) {
switch (param) {
case PARAM_MAIN: return make_unique<derived1>();
case PARAM_2: return make_unique<derived2>();
case ...: return make_unique<derived...>();
}
}
I solved it this way:
return unique_ptr<base>(dynamic_cast<base*>(std::move(
new derived1()
)));
So the point is that it has to be upcasted to base while its still raw, and only then be wrapped in the unique_ptr.
I appreciate simpler answers anyway. Especially those reasoning based on the internals of unique_ptr and the implementation.

Resources