2012-02-13 3 views
1

Могу ли я перегрузить конструктор std :: string?Перегрузка std :: string constructor

Я хочу создать конструктор, который принимает std :: wstring и возвращает std :: string. возможно ли и как?

Спасибо.

+0

Наследование со стороны std :: string нецелесообразно. Он не имеет виртуального деструктора и вызовет проблемы. – Casey

ответ

3

Могу ли я перегрузить станд :: строковый конструктор?

Нет, это потребует изменения декларации std::string.

Я хочу создать конструктор, который принимает std :: wstring и возвращает std :: string. возможно ли и как?

Вы можете иметь функцию преобразования вместо этого, как:

std::string to_string(std::wstring const& src); 

Однако, вы должны решить, что делать с символами, которые не могут быть представлены с использованием 8-битного кодирования std::string: стоит ли преобразовать их в многобайтовые символы или выбросить исключение. См. Функцию wcsrtombs.

+0

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

+0

Право. однако у вас может быть очень короткое имя для этой функции. Как 'std :: string operator ~ (std :: wstring const &)'. –

+2

@Maxim: Это не очень хорошее предложение. 'operator ~' не является «преобразованием» по интуиции. –

2

Скорее определить свободную функцию:

std::string func(const std::wstring &) 
{ 
} 
+2

Это невозможно в C++ (если вы имели в виду, что это оператор преобразования, который должен быть членом, если вы имеете в виду, что это что-то другое, тогда у меня нет идеи, что вы имеете в виду) – PlasmaHH

+0

@ PlasmaHH: вы правы, и вы должны были отказаться. Изменена функция free. – Benoit

1

Нет, вы не можете добавить никаких новых конструкторов в std::string. То, что вы можете сделать, это создать отдельную функцию преобразования:

std::string wstring_to_string(const wstring& input) 
{ 
    // Your logic to throw away data here. 
} 

Если вы (думаю, что вы) хотите, чтобы это произошло автоматически, я настоятельно рекомендую заново оценить эту идею. Вы вызовете себе значительное количество головных болей, поскольку wstring s автоматически рассматриваются как string, когда вы меньше всего этого ожидаете.

0

Это не правильный истинный способ сделать это, и я думаю, что я что-то курил, когда закодировал это, но он решает проблему. Проверьте последнюю функцию, `convert_str '.

#pragma once  

#include <memory> 
#include <string> 
#include <vector> 

#include <boost/utility/enable_if.hpp> 
#include <boost/type_traits/remove_const.hpp> 
#include <boost/type_traits/remove_pointer.hpp> 
#include <boost/type_traits/is_same.hpp> 
#include <boost/mpl/logical.hpp> 

template <typename Target, typename Source, typename cond> 
struct uni_convert { 
}; 

template <typename Target, typename Source > 
struct uni_convert<Target,Source, 
    typename boost::enable_if< boost::is_same<Target, Source>, int >::type > { 
    static Target doit(Source const& src) 
    { 

     return src; 
    } 
}; 

template <typename Cond > 
struct uni_convert<std::string,std::wstring, 
    Cond > { 
    static std::string doit(std::wstring const& src) 
    { 
     std::vector<char> space(src.size()*2, 0); 
     wcstombs(&(*(space.begin())), src.c_str(), src.size()*2); 
     std::string result(&(*(space.begin()))); 
     return result; 
    } 
}; 

template <typename Cond > 
struct uni_convert<std::wstring,std::string, 
    Cond > { 
    static std::wstring doit(std::string const& src) 
    { 
     std::vector<wchar_t> space(src.size()*2, 0); 
     mbstowcs(&(*(space.begin())), src.c_str(), src.size()*2); 
     std::wstring result(&(*(space.begin()))); 
     return result; 
    } 
}; 

template< typename TargetChar > 
std::basic_string<TargetChar> convert_str(std::string const& arg) 
{ 
    typedef std::basic_string<TargetChar> result_t; 
    typedef uni_convert< result_t, std::string, int > convertor_t; 
    return convertor_t::doit(arg); 
} 
+2

Как это лучше, чем 'boost :: lexical_cast (wstring)'? –

+0

Ах, это правильный истинный путь. Я не знал ;-) Спасибо! – dsign

+0

Думаю, вам нужно еще курить (- –