2015-07-23 2 views
0

Я хочу перенести часть моего кода на Python на код C++. Проблема, с которой я сталкиваюсь сейчас, когда функция может возвращать различные типы объектов - скажем, переменные одного класса или другие, в зависимости от некоторых условий (но не от типа аргумента), почти так:boost C++ метод, возвращающий разные типы объектов

def somefunc(var): 
    # obj1 is instance of Class1 
    # obj2 is instance of Class2 
    #.... some other code 
    if var == 1: 
     return obj1 
    elif var == 2: 
     return obj2 

И скажем, что у меня есть соответствующие классы, реализованные на C++. И теперь я хочу как-то вернуться из метода либо к экземпляру одного класса, либо другого. Я не знаю, как подойти к этой задаче - как должен выглядеть мой метод на C++ и как должен выглядеть BOOST_PYTHON_MODULE. Если бы кто-то мог предоставить простейший в мире экзамен с функцией C++, возвращающей instanced из разных классов, это было бы весьма признательно.

+1

Я не знаю подталкивание питона вещи, но boost.variant или boost.any, вероятно, будет полезно. –

+0

Предположим, что проблем с файлом python нет. С тех пор я чувствую, что все проблемы связаны со С ++. Можете ли вы представить простой пример C++, где 'boost.any' или' boost.variant' используются таким образом, что какой-то метод возвращает экземпляры разных типов (например, некоторые пользовательские Class1 или Class2)? Думаю, это было бы ответом на мой вопрос. – Jacobian

ответ

2

Как сказано в комментариях, настоящий вопрос: как вернуть разные типы из одной и той же функции в C++?

Для этого мы можем использовать boost.variant. Вот небольшой пример, который демонстрирует основные функции, нам нужно:

#include <iostream> 
#include <string> 
#include <boost/variant.hpp> 

boost::variant<int, std::string> fun (bool i) { 
    if (i) 
     return "Hello boost!\n"; 
    return 4711; 
} 

int main() 
{ 
    std::cout << fun(true) << fun(false) << std::endl; 
} 

Выход будет

Hello boost! 
4711 

Более подробное знакомство с особенностями boost.variant могут быть найдены в их tutorial.

Если возможные типы возврата не известны во время компиляции или их количество является большим, мы также можем использовать boost.any. Это более гибкий, но немного менее прямо вперед:

#include <iostream> 
#include <string> 
#include <boost/any.hpp> 

using namespace std::literals::string_literals; 

boost::any fun (bool i) { 
    if (i) 
     return "Hello boost!\n"s; 
    return 4711; 
} 

int main() 
{ 
    std::cout << boost::any_cast<std::string>(fun(true)) 
       << boost::any_cast<int>(fun(false)) << std::endl; 
} 

Если возможно, boost.variant, скорее всего, лучший инструмент для вашей проблемы.

+0

Отлично! И чтобы довести до конца до конца ответ, можете ли вы также предоставить простейший пример использования boost :: any? – Jacobian

+0

@ Jacobian Добавлено. Но вы, скорее всего, хотите boost.variant здесь. –

+0

Спасибо! Ты прав! Кажется, я должен использовать вариант. – Jacobian

1

Если эти классы могут наследовать один интерфейс, вы можете пойти с абстрактным классом интерфейса.

//Interface, abstract class .h file 

#pragma once 

namespace test 
{ 
    class IClass0 
    { 
     public: 
      virtual bool DoStuff() =0;  
    }; 
} 


//Class1 .h file 
#pragma once 
#include "IClass0.h" 

    namespace test 
    { 
     class Class1 : public IClass0 
     { 
      public: 
       virtual bool DoStuff();  
     }; 
    } 


//Class2 .h file 
#pragma once 
#include "IClass0.h" 

    namespace test 
    { 
     class Class2 : public IClass0 
     { 
      public: 
       virtual bool DoStuff();  
     }; 
    } 

И чем вы могли бы вернуть указатель на созданный экземпляр в качестве интерфейса

unique_ptr<IClass0> ReturnClassInstance() 
{ 
    if(condition1) 
    { 
     unique_ptr<Class1> ptr (new Class1()); 
     return move(ptr); 
    } 
    else 
    { 
     unique_ptr<Class2> ptr (new Class2()); 
     return move(ptr); 
    } 
} 
+0

В общем случае они не наследуются от одного интерфейса. Но все же я нахожу ваш ответ очень полезным! Благодаря! – Jacobian

Смежные вопросы