2015-01-16 1 views
3

Следующий код правильно вычерчивает значения 999 и «test» на консоль, но как мне вернуть эти значения? Что-то вроде прокомментированной строки было моей конечной целью; верните значение, которое затем я могу присвоить автоматической переменной (так как я не знаю тип, с которым я буду иметь дело). Я планирую использовать boost::lexical_cast, чтобы преобразовать это значение в std::string, чтобы вставить его в поле в базу данных.Как вернуть значение шаблона из boost :: apply_visitor?

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

Любые предложения приветствуются. Благодарю.

#include "stdafx.h" 
#include "boost\variant.hpp" 
#include <iostream> 
#include <map> 

struct DataMap 
{ 
    DataMap() {}; 

    typedef std::map<std::string, std::map<std::string, 
     boost::variant<int, std::string>>> ArtifactMap; 

    ArtifactMap::const_iterator begin() const { return _data.begin(); } 
    ArtifactMap::const_iterator end() const { return _data.end(); } 
    ArtifactMap _data; 
}; 

struct DataMapVisitor : public boost::static_visitor<> 
{ 
    template<typename T> 
    void operator()(const T& t) const { std::cout << t << std::endl; } 
}; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    DataMap dataMap; 
    std::map<std::string, boost::variant<int, std::string>> columns; 
    columns.insert(std::make_pair("Col1", 999)); 
    columns.insert(std::make_pair("Col2", "test")); 
    dataMap._data.insert(std::make_pair("Table1", columns)); 

    for (auto table : dataMap) 
    { 
     for (auto column : table.second) 
     { 
      boost::apply_visitor(DataMapVisitor(), column.second); 
      //auto value = boost::apply_visitor(DataMapVisitor(), column.second); 
     } 
    } 

    return 0; 
} 

Edit: В качестве обновления, следующий код имеет посетитель правильно возвращающий std::string. Я предполагаю, что нет способа, чтобы один посетитель возвращал несколько типов значений (т. Е. Возвращал значение string, если он равен string, возвращает значение int, если это int и т. Д.)?

class DataMapVisitor : public boost::static_visitor<std::string> 
{ 
public: 

    template<typename T> 
    std::string operator()(const T& value) const 
    { 
     try 
     { 
     return boost::lexical_cast<std::string>(value); 
     } 
     catch (boost::bad_lexical_cast&) 
     { 
     return ""; 
     } 
    } 
}; 

ответ

1

Если вещь, которую вы хотите вернуть, является вариантом, вы можете вернуть ее в качестве варианта. Надеюсь, это ответит на ваш вопрос.

#include <boost\variant.hpp> 
#include <iostream> 
#include <map> 

typedef boost::variant<int, std::string> TVariant; 

struct DataMap 
{ 
    DataMap() {}; 

    typedef std::map<std::string, std::map<std::string, TVariant>> ArtifactMap; 

    ArtifactMap::const_iterator begin() const { return _data.begin(); } 
    ArtifactMap::const_iterator end() const { return _data.end(); } 
    ArtifactMap _data; 
}; 

struct DataMapVisitor : public boost::static_visitor<TVariant> 
{ 
    template<typename T> 
    TVariant operator()(const T& t) const { 
     std::cout << t << std::endl; 
     return t; 
    } 
}; 


int main(int argc, char** args) 
{ 
    DataMap dataMap; 
    std::map<std::string, TVariant> columns; 
    columns.insert(std::make_pair("Col1", 999)); 
    columns.insert(std::make_pair("Col2", "test")); 
    dataMap._data.insert(std::make_pair("Table1", columns)); 

    for (auto table : dataMap) 
    { 
     for (auto column : table.second) 
     { 
      boost::apply_visitor(DataMapVisitor(), column.second); 
      auto value = boost::apply_visitor(DataMapVisitor(), column.second); 
     } 
    } 

    return 0; 
} 
Смежные вопросы