2017-01-13 2 views
2

автоматический вывод типов возврата возможно в C++ 14, но я пытаюсь написать что-то подобное в C++ 11 т.е.decltype (авто) в C++ 11 - выводя тип возвращаемого

Если бы я написать в C++ 14, было бы

struct MyTypeA{ 
    std::vector<int> _d; 
}; 

struct MyTypeB{ 
    int _id; 
    std::string _name; 
    MyTypeA _data; 
}; 

decltype(auto) MakeObject(const MyTypeA& obj) { 
    return std::make_tuple(obj._vec); 
} 

decltype(auto) MakeObject(const MyTypeB& obj) { 
    return std::make_tuple(obj._id, obj._name, std::make_tuple(MakeObject(obj._data))); 
} 

выше C++ 14 и я могу переписать MakeObject что-то подобное в C++ 11, как показано ниже,

auto MakeObject (const MyTypeA& obj) -> decltype(std::make_tuple(obj._d)){ 
    return std::make_tuple(obj._d); 
}; 

auto MakeObject (const MyTypeB& obj) -> decltype(std::make_tuple(obj._id, obj._name, std::make_tuple(MakeObject(obj._data)))){ 
    return std::make_tuple(obj._id, obj._name, std::make_tuple(MakeObject(obj._data))); 
}; 

и как вы можете см. У меня есть куча перегруженных функций, отличных от членов нс. Хотя это работает, это выглядит очень многословным и избыточным кодом. Есть ли лучший способ сделать это на C++ 11?

+3

Вы упомянули лямбда, но я не вижу ни одного лямбда в вашем вопросе. Вы имели в виду «trailing return types» вместо этого? – Angew

+3

Я не совсем понимаю, что вы говорите о лямбдах. Код, который вы опубликовали, не использует никакой лямбда-функции. Если lambdas (не имея именованной функции) достаточно для вас, вы можете легко их использовать, поскольку у них уже есть автоматический вывод типа возвращаемого типа, если в C++ 11 имеется только один оператор return. –

+0

Извините, ребята. Мой плохой, я наклеил не-лямбда-код и забыл изменить текст. Не используйте лямбда – blueskin

ответ

1

Есть ли лучший способ сделать это в C++ 11?

В то время как тип возврата регулярной функции не может быть выведен до C++ 14, тип возвращаемого значения лямбда может быть. И не захватывающая лямбда ведет себя как функция. Итак, в C++ 11 вы можете сделать

auto MakeObject = [](const MyTypeA& obj) { 
    return std::make_tuple(obj._vec); 
} 

Однако это не допускает перегрузки, которую вы используете. Если вам нужна перегрузка, конечный параметр decltype может быть лучшим выбором.

+0

точно, я не могу перегружать лямбды. Не уверен, есть ли способ сделать это – blueskin

0
#define RETURNS(...) decltype(__VA_ARGS__) { return __VA_ARGS__; } 

Тогда вы получите

auto MakeObject(const MyTypeA& obj) 
->RETURNS(std::make_tuple(obj._vec)) 

Это может или не может считаться лучше. Но он устраняет нарушение DRY.