2015-10-12 3 views
1

У меня возникли проблемы с поддержанием корректности константы после попытки получить экземпляр boost::any с помощью boost::any_cast ссылки.Как получить ссылку на данные, содержащиеся в boost :: any?

Мой код:

MyMap paramMapToSet; 
MyMap& paramMap = &paramMapToSet; 
const MyMap& constParamMap = &paramMapToSet; 

A hoe; 
paramMap.set(hoe, "structA"); 

// this works 
A& hoeRef = paramMap.getByRef<A>("structA"); 
hoeRef.myInt = 101; 
cout << paramMap.get<A>("structA").myInt << endl; // prints 101 

// as well as this: 
hoe = constParamMap.get<A>("structA"); 
cout << hoe.myInt << endl; 

// and this: 
const A& constHoeRef = paramMap.getByRef<A>("structA"); 
cout << constHoeRef.myInt << endl; 

// however this doesn't work, why?? (error message below) 
const A& constHoeRef = constParamMap.getByRef<A>("structA"); 
cout << constHoeRef.myInt << endl; 

Я также немного смущен относительно того, как поступать только последняя версия генерирует ошибку. Сообщение об ошибке я получаю это:

C:...\boost_1_58_0\boost\any.hpp:284: error: C2440: 'return' : cannot convert from 'const nonref' to 'A &' Conversion loses qualifiers

Где строка 284 выглядит следующим образом:

return any_cast<const nonref &>(const_cast<any &>(operand)); 

Он вызывается из строки ниже:

Реализация:

// a testing class: 
struct A{ 
    int myInt; 
    A() = default; 
    A(const A& other) : myInt(other.myInt) 
     { cout << "Class A is being copied" << endl; } 
}; 

// any-map implementation 
class MyMap{ 
public: 
    template<typename T> 
    T get(const std::string& path) const 
    { 
     return any_cast<T>(data.at(path)); 
    } 

    template<typename T> 
    const T& getByRef(const std::string& path) const 
    { 
     return any_cast<T&>(data.at(path)); // compiler originates the error from here 
    } 

    template<typename T> 
    T& getByRef(const std::string& path) 
    { 
     return any_cast<T&>(data.at(path)); 
    } 

    template<typename T> 
    void set(T val, const std::string& path) 
    { 
     data[path] = val; 
    } 

private: 
    std::map<std::string, boost::any> data; 
}; 

Возможно, вы думаете, что MyMap обеспечивает бесполезную функциональность упаковки, которая уже существует из коробки, howeve В реальной реализации есть методы get/set, которые автоматически создают вложенные карты внутри внутренней std :: map, обеспечивая классную гибкую DOM-структуру данных.

+1

Почему вы не делаете вопрос проще, написав меньше кодов. напишите только те коды, которые создают сомнение в вашем уме и оставляют остальное как «// делайте что-нибудь ..» или аналогичные способы. –

+1

@AnkitAcharya: Потому что это полярная противоположность того, что мы задаем авторам вопроса? http://stackoverflow.com/help/mcve '// do stuff' бессмысленно, бесполезно и раздражает. –

+1

@LightnessRacesinOrbit Я понимаю вашу точку, но все, что просто, как указано выше, может быть выражено и в простых кодах. thta означает лучше поставить небольшой тестовый код, а не огромный код PROJECT – CppNITR

ответ

4

Я просто догадываюсь, но, конечно же, & hellip;

return any_cast<const T&>(data.at(path)); 
//    ^^^^^^ 

& hellip; no?

+0

Данг, он работает наконец. Я не знал, что вы можете написать там const. Я подумал, что T get is it is const qualifier автоматически по пути, если это необходимо. – MatrixAndrew

+2

@AndrewVegvari: Нечеткое предположение, когда оно не компилируется, жалуется на отсутствие 'const', но все в порядке ... –