how extend std::string without derivation?
I would like to extend std::string (for example)
- without deriving a class and
- the method not being declared within the std::string class and
- without changing the library source code
think of the idea as a library plug-in/extension.
for instance, adding needed and commonly-used methods like
std::string::icompare()
std::string::ifind()
and such.
is there syntax for adding a method to an existing class if it's not
declared in the class?
I get compile errors that basically say this is impossible right now to do.
anybody have an idea?
google groups search box is not working or I would look it up myself
and there is no help link to have it fixed, it just causes a delay and
reloads the page.
I would like to see this library plugin idea a part of the language.
If I use std::basic_string without parameters I get errors because I am
not using template parameters.
I think once I got an error message about the return type not liking
parameterized template types or something.
icompare.cpp:87:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string::stringlower(std::basic_string<char> s) {
std::basic_string std::basic_string::stringupper(std::basic_string<char> s) {
//not sure if std::basic_string:: will solve conflicting namespaces between <locale> and <string>
locale loc;
// get collate facet:
const collate<char>& coll = use_facet<collate<char> >(loc);
for (size_t i=0; i < s.size(); i++) {
s[i]=toupper(s[i]);
}
return s;
}
If I use std::basic_string<char> all the way, I get errors because
basic_string is being used without (?) template parameters according to
gcc 4.9.0.
usually this is sufficient and the rest is auto-filled. do I submit a
gcc bug report?
icompare.cpp:97:34: error: 'template<class _CharT, class _Traits, class _Alloc> class std::basic_string' used without template parameters
std::basic_string<char> std::basic_string::stringupper(std::basic_string<char> s) {
std::basic_string<char> std::basic_string::stringupper(std::basic_string<char> s) {
//not sure if std::basic_string:: will solve conflicting namespaces between <locale> and <string>
locale loc;
// get collate facet:
const collate<char>& coll = use_facet<collate<char> >(loc);
for (size_t i=0; i < s.size(); i++) {
s[i]=toupper(s[i]);
}
return s;
}
I think I am stuck with inheritance, which means
- learning a new class name which nobody knows what it is and probably
won't remember
- writing duplicate class documentation, etc.
icompare.cpp:12:124: error: no 'int std::locale::icompare(const char_type*, const char_type*, const char_type*, const char_type*) const' member function declare
d in class 'std::locale'
int std::locale::icompare(const char_type* low1, const char_type* high1, const char_type*low2, const char_type* high2) const {
^
icompare.cpp:41:9: error: specializing member 'std::basic_string<char>::icompare' requires 'template<>' syntax
int std::string::icompare(std::string second) {
^
icompare.cpp:58:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string<char>::localestringlower(std::basic_string<char> s) {
^
icompare.cpp:65:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string::localestringupper(std::basic_string<char> s) {
^
icompare.cpp:72:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string::stringlower(std::basic_string<char> s) {
^
icompare.cpp:79:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string::stringupper(std::basic_string<char> s) {
^
icompare.cpp:87:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string::stringlower(std::basic_string<char> s) {
^
icompare.cpp:97:34: error: 'template<class _CharT, class _Traits, class _Alloc> class std::basic_string' used without template parameters
std::basic_string<char> std::basic_string::stringupper(std::basic_string<char> s) {
^
icompare.cpp: In function 'std::basic_string<char> stringupper(std::basic_string<char>)':
icompare.cpp:99:9: error: 'locale' was not declared in this scope
locale loc;
^
icompare.cpp:99:9: note: suggested alternative:
In file included from f:/x86_64-4.9.0-release-posix-sjlj-rt_v3-rev2/mingw64/x86_64-w64-mingw32/include/c++/locale:39:0,
from icompare.cpp:5:
f:/x86_64-4.9.0-release-posix-sjlj-rt_v3-rev2/mingw64/x86_64-w64-mingw32/include/c++/bits/locale_classes.h:62:9: note: 'std::locale'
class locale
^
icompare.cpp:101:15: error: 'collate' does not name a type
const collate<char>& coll = use_facet<collate<char> >(loc);
^
icompare.cpp: At global scope:
icompare.cpp:108:9: error: specializing member 'std::basic_string<char>::icompare' requires 'template<>' syntax
int std::string::icompare(std::string second) {
^
#if !defined(ICOMPARE_H)
#define ICOMPARE_H
#include <string>
#include <cctype>
#include <locale>
#include <uchar.h>
//namespace std {
//this looks like something you could do with a template to eliminate the redundancy...
//in <locale>
template<class char_type>
int std::locale::icompare(const char_type* low1, const char_type* high1, const char_type*low2, const char_type* high2) const {
//not sure if this is method is correct. I think it is.
//not including high1 or high2 but including low1 and low2
//size comparison first.
if (high1-low1<high2-low2) {
return -1;
} else if (high1-low1>high2-low2) {
return 1;
} else if (high1==low1>high2==low2) {
return 0;
} else {
//lengths are equal. compare the chars
//specify locale::tolower() to avoid conflict with cctype tolower()?
while(low1 < high1 && std::tolower(*low1)==std::tolower(*low2)) {
low1++;
low2++;
}
//fell through loop, either *low1!=*low2 or low1>=high1
if (std::tolower(*low1)!=std::tolower(*low2) && low1<high1) {
if (std::tolower(*low1)<std::tolower(low2)) {
return -1;
} else {
return 1;
}
}
}
}
int std::string::icompare(std::string second) {
std::basic_string<char> first=this->data();
std::locale loc;
// get collate facet:
const std::collate<char>& coll = std::use_facet<std::collate<char> >(loc);
first=std::basic_string<char>::stringlower(first);
second=std::basic_string<char>::stringlower(second);
return std::collate::compare(
first.c_str(),
first.c_str()+first.size(),
second.c_str(),
second.c_str()+second.size()
);
}
//in std::basic_string
std::basic_string std::basic_string<char,std::char_traits<char> >::localestringlower(std::basic_string<char,std::char_traits<char> > s) {
//not sure if locale:: will solve conflicting namespaces between <locale> and <string>
for (size_t i=0; i < s.size(); i++) {
s[i]=tolower(s[i]);
}
return s;
}
std::basic_string std::basic_string<char>::localestringupper(std::basic_string<char> s) {
//not sure if locale:: will solve conflicting namespaces between <locale> and <string>
for (size_t i=0; i < s.size(); i++) {
s[i]=toupper(s[i]);
}
return s;
}
std::basic_string std::basic_string<char>::stringlower(std::basic_string<char> s) {
//ASCII version
for (size_t i=0; i < s.size(); i++) {
s[i]=tolower(s[i]);
}
return s;
}
std::basic_string std::basic_string<char>::stringupper(std::basic_string<char> s) {
//ASCII version
for (size_t i=0; i < s.size(); i++) {
s[i]=toupper(s[i]);
}
return s;
}
std::basic_string std::basic_string<char>::stringlower(std::basic_string<char> s) {
//not sure if std::basic_string:: will solve conflicting namespaces between <locale> and <string>
std::locale loc;
// get collate facet:
std::collate<char>& coll = use_facet<collate<char> >(loc);
for (size_t i=0; i < s.size(); i++) {
s[i]=tolower(s[i]);
}
return s;
}
std::basic_string<char> std::basic_string<char>::stringupper(std::string s) {
//not sure if std::basic_string:: will solve conflicting namespaces between <locale> and <string>
std::locale loc;
// get collate facet:
std::collate<char>& coll = use_facet<collate<char> >(loc);
for (size_t i=0; i < s.size(); i++) {
s[i]=toupper(s[i]);
}
return s;
}
int std::string::icompare(std::basic_string<char> second) {
std::basic_string<char> first=this->data();//syntax?
locale loc;
// get collate facet:
const collate<char>& coll = use_facet<collate<char> >(loc);
first=std::basic_string::stringlower(first);
second=std::basic_string::stringlower(second);
return collate::compare(
first.c_str(),
first.c_str()+first.size(),
second.c_str(),
second.c_str()+second.size()
);
}
//};
/*
icompare.cpp:12:124: error: no 'int std::locale::icompare(const char_type*, const char_type*, const char_type*, const char_type*) const' member function declare
d in class 'std::locale'
int std::locale::icompare(const char_type* low1, const char_type* high1, const char_type*low2, const char_type* high2) const {
^
icompare.cpp:41:9: error: specializing member 'std::basic_string<char>::icompare' requires 'template<>' syntax
int std::string::icompare(std::string second) {
^
icompare.cpp:58:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string<char,std::char_traits<char> >::localestringlower(std::basic_string<char,std::char_traits<char> > s) {
^
icompare.cpp:65:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string<char>::localestringupper(std::basic_string<char> s) {
^
icompare.cpp:72:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string<char>::stringlower(std::basic_string<char> s) {
^
icompare.cpp:79:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string<char>::stringupper(std::basic_string<char> s) {
^
icompare.cpp:87:5: error: invalid use of template-name 'std::basic_string' without an argument list
std::basic_string std::basic_string<char>::stringlower(std::basic_string<char> s) {
^
icompare.cpp:97:29: error: specializing member 'std::basic_string<char>::stringupper' requires 'template<>' syntax
std::basic_string<char> std::basic_string<char>::stringupper(std::string s) {
^
*/
#endif
as far as errors go, I can't win, the things I do to fix problems just
give different errors.
as for adding to the language to make this possible,
cons:
- the template type, if any, is lost when you go outside the file.
- while this provides native extension of the std c++ library, because
it's native and not in the compiler, other people who want the content
and are trying to compile the code with this
enhancement/compiler-library-plug-in code won't have it unless you
supply it somehow (people supply it of course).
- documentation?
- might defeat the definition of "standard" in standard template
library? implications?
pros:
- native extension of the std c++ library
- content may possibly be submittable to the standards folk and it be a
language plug-in future standard? is this a bad format/way of doing
things or acceptable? or desireable?
- added functionality now
- possible easy (and working!) library enhancements to the standard if accepted
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]