Я реализовал строковый класс с именем Str и хочу добавить преобразование в тип bool, чтобы использовать объект Str в качестве условия.
Класс Str довольно прост и основан на другом шаблонном классе, называемом Vec, который похож на векторный класс STL.Ниже я скопировал основные части определения
class Str
{
friend std::istream& operator>>(std::istream&, Str&);
private:
Vec<char> data;
public:
typedef Vec<char>::size_type size_type;
typedef Vec<char>::iterator iterator;
typedef Vec<char>::const_iterator const_iterator;
iterator begin() { return data.begin(); }
const_iterator begin() const { return data.begin(); }
iterator end() { return data.end(); }
const_iterator end() const { return data.end(); }
//[...]
char& operator[](size_type i) { return data[i]; }
const char& operator[](size_type i) const { return data[i]; }
Str& operator+=(const Str& s)
{
std::copy(s.data.begin(), s.data.end(), std::back_inserter(data));
return *this;
}
};
Str::operator bool() const
{
if (data.size() > 0)
return true;
return false;
}
Все работает нормально, за исключением того, что теперь, если я попытаюсь, например, сделать следующее:
Str greeting = "Hello, " + name + "!";
, тогда я получуОшибка компиляции: «оператор +»: 2 перегрузки имеют похожие преобразования, это может быть «оператор Str + (const Str &, const Str &)» или «встроенный оператор C ++ + (const char [8], int)».
Я понимаю причину ошибки, но я не уверен, как ее исправить. Как я могу обойти это?
Спасибо.
РЕДАКТИРОВАТЬ: ниже у меня естьдобавлен минимальный, полный и проверяемый пример:
#include <iterator>
#include <vector>
#include<iostream>
using namespace std;
class Str
{
private:
std::vector<char> data;
public:
typedef std::vector<char>::size_type size_type;
typedef std::vector<char>::iterator iterator;
typedef std::vector<char>::const_iterator const_iterator;
iterator begin() { return data.begin(); }
const_iterator begin() const { return data.begin(); }
iterator end() { return data.end(); }
const_iterator end() const { return data.end(); }
// default constructor must be defined explicitly, since non-default constructors are also defined
Str() { }
Str(const size_type n, const char c) : data(n, c) { }
Str(const char* cp)
{
std::copy(cp, cp + std::strlen(cp), std::back_inserter(data));
}
// Since this is a template, the iterators can be anything: pointers in an array of chars, std::vector<string> iterators, std::std::vectortor<string> iterators, std::list<string> iterators, etc.
template <class In> Str(In b, In e)
{
std::copy(b, e, std::back_inserter(data));
}
char& operator[](size_type i) { return data[i]; }
const char& operator[](size_type i) const { return data[i]; }
Str& operator+=(const Str& s)
{
std::copy(s.data.begin(), s.data.end(), std::back_inserter(data));
return *this;
}
size_type size() const
{
return data.size();
}
// conversion operators
operator std::vector<char>() const;
operator bool() const;
template <class In> void insert(iterator dest, In b, In e)
{
data.insert(dest, b, e);
}
};
Str operator+(const Str& s1, const Str& s2)
{
Str s = s1;
s += s2;
return s;
}
Str::operator std::vector<char>() const
{
std::vector<char> ret = data;
return ret;
}
Str::operator bool() const
{
if (data.size() > 0)
return true;
return false;
}
int main()
{
Str name = "Joe";
Str greeting = "Hello, " + name + "!";
return 0;
}