2013-11-17 2 views
1

Я хочу сделать что-то перегруженное с другим значением параметра в C++.Как я могу вернуть другой тип в соответствии со значением параметра в C++?

Что-то вроде динамического языка, таких как Python:

def foo(str): 
    if str == "a": 
    return str 
    if str == "b": 
    return true 
    if str == "c": 
    return 1 

Есть ли какая-модель RTTI в C++, чтобы заставить его работать?

подталкивания :: любых потребности неявного определить тип при вызове функции:

boost::any foo() {...} 

auto result = boost::any_cast<int>(foo("c")); 

Как я могу определить результат вар без неявного дать ВНУТР?

Другими словами, я хочу, чтобы сделать эту семантику ниже:

result = foo("a") 
+8

'boost :: variant',' boost :: any'. –

+3

, исходя из строго типизированных языков, можете ли вы привести пример, где это действительно полезно? Я не уверен, что хотел бы вызвать функцию с неоднозначным возвращаемым значением. – Alex

+1

С тех пор, как набирается C++, программисты работают, чтобы вернуться, ну, вещи одного типа. Все остальное становится очень волосатым. (Как вы справляетесь с такой стоимостью?) –

ответ

0

Я думаю, что лучший способ заключается в использовании объединение внутри структуры с полем типа.

enum var_type{X_BOOL,X_INT,X_DOUBLE,X_STRING /*add more if needed*/}; 

struct var{ 
    var_type type; 
    union{ 
    bool bool_var; 
    int int_var; 
    double dbl_var; 
    string str_var; 
    /*add more here if needed...*/ 
    }var; 
}; 

при установке вара вы должны также задать тип, и когда вы получите это в качестве возвращаемого значения, вы должны проверить тип и взять вар в соответствии с ним.

+0

Вы повторно используете 'boost :: variant', плохо. –

+0

Дело в том, как это сделать, я не собирался предлагать полную реализацию. вы можете добавить сеттеры как: setInt, setBool, setString и т. д. и getters, а также исключить исключения, если вы используете его неправильно ... – SHR

1

Есть два вида языков, которые позволяют то, что вы просите:

  • динамических языков
  • зависимым от типизированных языков

C++ является ни: функция подписи не зависит от значения аргументов, переданных ему. Это, однако, может зависеть от типа аргументов или значения параметров шаблона нетиповых:

struct A{}; struct B{}; struct C{}; 

auto foo(A) -> std::string; 
auto foo(B) -> bool; 
auto foo(C) -> int; 

Если вы действительно хотите выбор выполнения правильного типа, то статический типа результата функции является объединение типов, которые он может вернуть; это может быть выражено с помощью чисто boost::variant (который является синтаксическим сахаром для помеченной союза):

auto foo(std::string const&) -> boost::variant<bool, int, std::string>; 

Конечно, это означает, что результат boost::variant<bool, int, std::string>, а не либо одно из этих трех; это именно то, что мы хотим. Затем пользователь должен проверить фактический тип, и если вы прочтете документацию, вы увидите, что есть несколько способов сделать это.

+0

Поддерживает ли boost :: varient support std :: vector ? – xunzhang

+0

@xunzhang: 'boost :: variant' поддерживает любой тип, даже типы, которые (например,' std :: string' или 'std :: vector ') обрабатывают память и, следовательно, требуют правильного вызова построения копии, назначения копирования и уничтожения , Он даже поддержит 'std :: map >' если вы хотите :) –

+0

Моя проблема в том, как я могу преобразовать тип boost :: variant в тип int? – xunzhang