Вы не можете деактивировать определенную функцию класса (здесь std :: basic_string), поскольку именно его интерфейс явно (и официально) разрешает эту манипуляцию. Попытка перегрузить оператора только испортит ситуацию.
Теперь вы можете "обернуть" std :: basic_string в другой класс , используя частное наследование или композицию, а затем использовать открытый интерфейс в качестве прокси для части std :: basic_string, но только для функций Вы хотите быть пригодными для использования.
Я рекомендую сначала заменить строковые типы на typedefs:
namespace myapp
{
typedef std::string String;
typedef std::wstring UTFString;
}
Затем, после того как ваше приложение скомпилируется нормально после замены std :: string и std :: wstring на myapp :: String и myapp :: UTFString (это примеры имен), вы определяете класс оболочки где-то:
namespace myapp
{
/** std::basic_string with limited and controlled interface.
*/
template< class _Elem, class _Traits, class _Ax >
class limited_string
{
public:
typedef std::basic_string< _Elem , _Traits, _Ax > _String; // this is for easier writing
typedef limited_string< _Elem, _Traits, _Ax > _MyType; // this is for easier writing
private:
_String m_string; // here the real std::basic_string object that will do all the real work!
public:
// constructor proxies... (note that those ones are not complete, it should be exactly the same as the original std::basic_string
// see some STL docs to get the real interface to rewrite)
limited_string() : m_string {}
limited_string( const _MyType& l_string ) : m_string( l_string.m_string ) {}
limited_string( const _Elem* raw_string ) : m_string( raw_string ) {}
//... etc...
// operator proxies...
_MyType& operator= ( const _MyType& l_string )
{
m_string = l_string.m_string;
}
// etc...
// but we don't want the operator += with int values so we DON'T WRITE IT!
// other function proxies...
size_t size() const { return m_string.size(); } // simply forward the call to the real string!
// etc...you know what i mean...
// to work automatically with other STL algorithm and functions we add automatic conversion functions:
operator const _Elem*() const { return m_string.c_str(); }
// etc..
};
}
... тогда вы просто заменяете эти строки:
// instead of those lines...
//typedef std::string String;
//typedef std::wstring UTFString;
// use those ones
typedef limited_string< char, std::char_traits<char>, std::allocator<char> > String; // like std::string typedef
typedef limited_string< wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > UTFString; // like std::wstring typedef
... и ваш пример потерпит крах:
error C2676: binary '+=' : 'myapp::UTFString' does not define this operator or a conversion to a type acceptable to the predefined operator
error C2676: binary '+=' : 'myapp::String' does not define this operator or a conversion to a type acceptable to the predefined operator
Вот полный код тестового приложения, которое я написал, чтобы доказать это (скомпилировано на vc9):
#include <string>
#include <iostream>
namespace myapp
{
/** std::basic_string with limited and controlled interface.
*/
template< class _Elem, class _Traits, class _Ax >
class limited_string
{
public:
typedef std::basic_string< _Elem , _Traits, _Ax > _String; // this is for easier writing
typedef limited_string< _Elem, _Traits, _Ax > _MyType; // this is for easier writing
private:
_String m_string; // here the real std::basic_string object that will do all the real work!
public:
// constructor proxies... (note that those ones are not complete, it should be exactly the same as the original std::basic_string
// see some STL docs to get the real interface to rewrite)
limited_string() : m_string {}
limited_string( const _MyType& l_string ) : m_string( l_string.m_string ) {}
limited_string( const _Elem* raw_string ) : m_string( raw_string ) {}
//... etc...
// operator proxies...
_MyType& operator= ( const _MyType& l_string )
{
m_string = l_string.m_string;
}
// etc...
// but we don't want the operator += with int values so we DON'T WRITE IT!
// other function proxies...
size_t size() const { return m_string.size(); } // simply forward the call to the real string!
// etc...you know what i mean...
// to work automatically with other STL algorithm and functions we add automatic conversion functions:
operator const _Elem*() const { return m_string.c_str(); }
// etc..
};
// instead of those lines...
//typedef std::string String;
//typedef std::wstring UTFString;
// use those ones
typedef limited_string< char, std::char_traits<char>, std::allocator<char> > String; // like std::string typedef
typedef limited_string< wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > UTFString; // like std::wstring typedef
}
int main()
{
using namespace myapp;
int age = 27;
UTFString str = UTFString(L"User's age is: ");
str += age; // compilation error!
std::wcout << str << std::endl;
String str2 = String("User's age is: ");
str2 += age; // compilation error!
std::cout << str2 << std::endl;
std::cin.ignore();
return 0;
}
Я думаю, это решит вашу проблему, но вам придется обернуть все функции.