Saving values ​​of any type as the type originally supplied in the factory template in C ++?

This is a slightly different question for this ([ Access to a method from a template derived class without using virtual functions in C ++? ), Which I recently asked.

I would like to instantiate an object using the factory template method, and then we can only set and get the value based on the original type provided to this element.

Here is a brief example of what I'm trying to achieve:

boost::shared_ptr<Item> item = Item::create<float>();

item->setValue(5);                  // conversion to 5.0 in setting the value
float value = item->value();        // returned value = 5.0

In fact, the only time setValue fails is the lack of an implicit conversion from what was set to the initial "type" of the internal value in Item.

So, if I made the entire Item class a template that accepts a type, I would need to specify the type of the value each time I created a generic pointer to an Item that is really uninteresting to me.

The next approach I took was to try to save the initial type in the class and use boost :: any for internal storage, casting the internal type to the first type specified if there was an implicit conversion. However, I slowed down to store and compare type information, initially looking at std :: type_info, but since setValue took boost :: any, there was no way to compare what was actually passed.

(A small extension for this may provide a variant option in the template argument when creating and returning a value in the original given type.)

, - , , , , - , ?

+3
4

boost:: any , . - . , template<typename T> class ItemOfType<T> : public Item. Item::create<T> . U, , dynamic_cast this ItemOfType<U>*. T==U.

, a U a T. , create<T> U, Item::operator=(U const) T.

+1

:

boost::shared_ptr<Item> item1 = Item::create<float>();
boost::shared_ptr<Item> item2 = Item::create<string>();

item1 item2 () : boost:: shared_ptr. , :

item2.setValue("foo");

:

item1.setValue("foo");

, " , , , setValue (setValue <float> (5) )". , , , . Item, :

boost::shared_ptr<Item<float> > item = Item<float>::create();

setValue() .

+2

Does this work for you?

#include <iostream>
#include <boost/shared_ptr.hpp>

using namespace std;
using namespace boost;

template<typename T> class Item
{
    Item(); // prohibited
    Item (const T & t) : m_value(t) {}
public :
    static shared_ptr<Item<T>> Create(const T & t) 
    { return shared_ptr<Item<T>>(new Item<T>(t)); }
    const T & getValue() const { return m_value; }
    void setValue(const T & v) { m_value = v; }
private :
    T m_value;
};

template<typename T> class Factory
{
public :
    static shared_ptr<Item<T>> CreateItem(const T & value)
    { return Item<T>::Create(value); }
};

void main()
{
    shared_ptr<Item<int>> a = Factory<int>::CreateItem(5);
    shared_ptr<Item<float>> b = Factory<float>::CreateItem(6.2f);
    std::cout << a->getValue() << std::endl;
    std::cout << b->getValue() << std::endl;
    a->setValue(3);
    b->setValue(10.7f);
    std::cout << a->getValue() << std::endl;
    std::cout << b->getValue() << std::endl;
}
  • edit - more constant nationalism is imposed.
+2
source

It sounds a lot like boost.any . Have you already looked at this?

+1
source

Source: https://habr.com/ru/post/1720263/


All Articles