РЕДАКТИРОВАТЬ: благодаря ответам я смог решить все проблемы с моим кодом. Я выкладываю здесь решение: оно может пригодиться кому-то в будущем. В частности, предложение об использовании прокси-класса оказалось очень полезным! Пример не рассматривает все случаи, но добавить вариант к варианту будет тривиально!
Я пишу пользовательский класс C ++ (C11 - Linux), который ведет себя как неупорядоченная карта {ключ, значение} . Я хотел бы перегрузить оператор [] , чтобы я мог использовать класс с тем же синтаксисом, что и у неупорядоченной карты: объект [ключ] вернул бы значение,
Проблема в том, что мне нужен объект [ключ] для возврата типа варианта. Я могу хранить внутренне значение в виде строки или структуры, но когда я получаю его с помощью object [key] , , мне нужно, чтобы возвращаемое значение было int , float или string в зависимости от некоторых внутренних условий, определенных во время выполнения .
Вот почему я думал об использовании boost :: option library ... но я открыт для любых других предложений. Единственное ограничение заключается в том, что класс test (в примере) должен быть скомпилирован как разделяемая библиотека .so, и что код должен быть C11-совместимым (я имею в виду, компилируемым GNU g ++ 4.8.5).
Я написал простой пример, чтобы показать, какое поведение я хотел бы Этот пример ничего не значит. Это просто, чтобы проиллюстрировать вид ошибки, которую я получаю. Реальный класс, который я пишу, имеет другую структуру, но использование перегрузки bool :: variable и operator [] одинаково.
test.cpp
#include <boost/variant.hpp>
typedef boost::variant<int, float> test_t;
class Test
{
int i ;
float f;
void set(int randomint, test_t tmp){
if ( randomint == 0 ) i = boost::get<int>(tmp);
else f = boost::get<float>(tmp);
}
test_t get(int randomint){
if ( randomint == 0 ) return i;
else return f;
}
struct IntOrFloat {
int randomint;
Test *proxy;
explicit operator int () const
{ return boost::get<int>(proxy->get(randomint)); }
void operator= (int tmp)
{ proxy->set(randomint, tmp); }
explicit operator float () const
{ return boost::get<float>(proxy->get(randomint)); }
void operator= (float tmp)
{ proxy->set(randomint, tmp); }
};
public:
IntOrFloat operator [](int randomint)
{ return IntOrFloat{randomint, this}; }
const IntOrFloat operator [](int randomint) const
{ return IntOrFloat{randomint, (Test *) this}; }
};
main.cpp
#include <iostream>
#include <boost/variant.hpp>
#include "test.cpp"
#define INTEGER 0
#define FLOAT 1
int main (void) {
Test test;
int i = 3;
float f = 3.14;
test[INTEGER] = i;
test[FLOAT] = f;
int x = (int) test[INTEGER];
float y = (float) test[FLOAT];
std::cout << x << std::endl;
std::cout << y << std::endl;
return 0;
}
Для компиляции и запуска
g++ -fPIC -std=c++11 -shared -rdynamic -o test.so test.cpp
g++ -std=c++11 -o test main.cpp -Lpath/to/the/test.so -l:test.so
LD_LIBRARY_PATH="path/to/the/test.so" ./test