unique_ptr upcast in return - c++11

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.

Related

Is it possible to return multiple types through a function?

I wanted to know if its possible to return a function that could either return a boolean or a void ? I know I could use std::optional however that is available only in C++17 and my code base is C++11. I would like something like this
xxx process(int a)
{
if (a==1)
return true;
if (a==2)
return false;
if (a==3)
.... //return nothing
}
For returning two values I use a std::pair (usually typedef'd).
In C++11 and newer, you should use std::tuple for more than two return results.
The abstract example using the tuple
std::tuple<bool, int> process(int a)
{
if (a==1)
return std::make_tuple(true, 0);
if (a==2)
return std::make_tuple(false, 0);
if (a==3)
return std::make_tuple(false, 1);
}
A variant might be a better match:
According to your requirement: a function that could either return a boolean or a void
See at: http://en.cppreference.com/w/cpp/utility/variant
The class template std::variant represents a type-safe union. An
instance of std::variant at any given time either holds a value of one
of its alternative types, or it holds no value (this state is hard to
achieve, see valueless_by_exception).
If you don't want to write an equivalent of std::optional yourself use an enum.
enum class Result
{
False,
True,
Nothing // or whatever name makes sense in your use case
};

Combining 'using' and 'reinterpret_cast'

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"},

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.

Create additional D3.js symbols

D3 already features a bunch of symbols, but I'd like to add a custom one. So that I could for example just call d3.svg.symbol().type('custom') in my code.
This cannot be done directly since the array of symbol definitions is not accessible from the API.
You can see in the source code HERE that the symbol definitions are stored in a d3.map called d3_svg_symbols. The only part of this map that gets exposed to the public API is the array of keys. This is done by calling the .keys() method of the map, HERE.
d3.svg.symbolTypes = d3_svg_symbols.keys();
The definitions themselves are never exposed, and so you cannot add definitions directly as you had hoped.
You can, however, construct a workaround without too much difficulty. One way would be to create a map of your custom symbols, and create a function based on the existing one for the built-in symbols. For example:
// DEFINE A COUPLE OF CUSTOM SYMBOLS
var customSymbolTypes = d3.map({
'custom-symbol-1': function(size) {
// returns a path-data string
},
'custom-symbol-2': function(size) {
// returns a path-data string
}
});
// CREATE A CUSTOM SYMBOL FUNCTION MIRRORING THE BUILT-IN FUNCTIONALITY
d3.svg.customSymbol = function() {
var type,
size = 64; // SET DEFAULT SIZE
function symbol(d,i) {
// GET THE SYMBOL FROM THE CUSTOM MAP
return customSymbolTypes.get(type.call(this,d,i))(size.call(this,d,i));
}
// DEFINE GETTER/SETTER FUNCTIONS FOR SIZE AND TYPE
symbol.type = function(_) {
if (!arguments.length) return type;
type = d3.functor(_);
return symbol;
};
symbol.size = function(_) {
if (!arguments.length) return size;
size = d3.functor(_);
return symbol;
};
return symbol;
};
Then, you could create a function to check if a symbol is in the list of built-in symbols, and if it's not, assume it is a custom symbol:
function getSymbol(type, size) {
// SIZE DEFAULTS TO 64 IF NOT GIVEN
size = size || 64;
// IF TYPE IS ONE OF THE BUILT-IN TYPES, CALL THE BUILT-IN FUNCTION
if (d3.svg.symbolTypes.indexOf(type) !== -1) {
return d3.svg.symbol().type(type).size(size)();
}
// OTHERWISE, CALL THE CUSTOM SYMBOL FUNCTION
else {
return d3.svg.customSymbol().type(type).size(size)();
}
}
HERE is a demo of this method in action.
I'll admit it seems kind of crazy to have to re-implement the whole symbol function like that. It might be worth a feature request on the github page asking to be able to provide a custom map of symbol definitions that could be read into the built-in method. Anyway, I hope that helps for now.

C++ boost::shared_ptr & boost::weak_ptr & dynamic_cast

I have something like this:
enum EFood{
eMeat,
eFruit
};
class Food{
};
class Meat: public Food{
void someMeatFunction();
};
class Fruit: public Food{
void someFruitFunction();
};
class FoodFactory{
vector<Food*> allTheFood;
Food* createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
if(food)
allTheFood.push_back(food);
return food;
}
};
int foo(){
Fruit* fruit = dynamic_cast<Fruit*>(myFoodFactory->createFood(eFruit));
if(fruit)
fruit->someFruitFunction();
}
now I want to change my application to use boost shared_ptr and weak_ptr such that i can delete my food instance in a single place. it would look like this:
class FoodFactory{
vector<shared_ptr<Food> > allTheFood;
weak_ptr<Food> createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
shared_ptr<Food> ptr(food);
allTheFood.push_back(ptr);
return weak_ptr<Food>(ptr);
}
};
int foo(){
weak_ptr<Fruit> fruit = dynamic_cast<weak_ptr<Fruit> >(myFoodFactory->createFood(eFruit));
if(shared_ptr<Fruit> fruitPtr = fruit.lock())
fruitPtr->someFruitFunction();
}
but the problem is that the dynamic_cast doesn't seem to work with weak_ptr
how do I get a weak_ptr<Fruit> out of a weak_ptr<Food> if i know that the object it points to is of derived type?
Direct casting from weak_ptr<A> to weak_ptr<B> will surely don't work, I think you have to convert it to a shared_ptr and then use the casting functionality of shared_ptr:
weak_ptr<Food> food = myFoodFactory->createFood(eFruit)
weak_ptr<Fruit> fruit = weak_ptr<Fruit>(dynamic_pointer_cast<Fruit>(food.lock());
You cannot use dynamic_cast with shared_ptr because it would require to change the template of the object. What in fact you want to do is a dynamic_cast on the internal pointer. To do this you could do a dynamic_cast on the pointer returned by get but that would not be so clean because the reference would not be shared(irrelevant in your case since you're using weak_ptr but relevant when using shared_ptr) and creating a share_ptr on this would be undefined resulting on a double delete.
Use dynamic_pointer_cast to do this but the two types still need to be related. In other words dynamic_cast<T*>(r.get()) needs to be well formed.
you can use BOOST_DISABLE_THREADS to improve performance if you're not bound to multithreading, see https://stackoverflow.com/a/8966130/1067933

Resources