Наследовать stl::list<T> as string<T>
От: Su34 Россия  
Дата: 26.11.22 23:29
Оценка:
Можно ли как-то написать наследованный шаблон от stl::list<T> так чтобы элементами списка был string<T>.
list<T> as list<basic_string<T> >
Спасибо!
Re: Наследовать stl::list<T> as string<T>
От: rg45 СССР  
Дата: 26.11.22 23:57
Оценка: +1
Здравствуйте, Su34, Вы писали:

S>Можно ли как-то написать наследованный шаблон от stl::list<T> так чтобы элементами списка был string<T>.

S>list<T> as list<basic_string<T> >
S>Спасибо!

Не полностью уверен, что правильно понял задачу. Предположу два возможных варианта:

1. С использованием наследования, как и было сказано:

template <typename T>
struct list_of_string : std::list<std::basic_string<T>>
{
  using list = std::list<std::basic_string<T>>; // injected name
  using list::list;                             // using basic constructors
};


2. Просто шаблонный алиас:

template <typename T>
using list_of_string = std::list<std::basic_string<T>>;


Использование для обоих вариантов одинаковое: list_of_string<char>, list_of_string<wchar_t>, etc.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 27.11.2022 0:30 rg45 . Предыдущая версия . Еще …
Отредактировано 27.11.2022 0:15 rg45 . Предыдущая версия .
Отредактировано 27.11.2022 0:03 rg45 . Предыдущая версия .
Отредактировано 26.11.2022 23:59 rg45 . Предыдущая версия .
Re: Наследовать stl::list<T> as string<T>
От: Su34 Россия  
Дата: 27.11.22 00:31
Оценка:
Здравствуйте, Su34, Вы писали:

S>Можно ли как-то написать наследованный шаблон от stl::list<T> так чтобы элементами списка был string<T>.

S>list<T> as list<basic_string<T> >
S>Спасибо!
Хочу пояснить условие задачи:
 template <class T> class basic_text
{
    typedef list<string<T>> text_t;
    text_t    _text;
    // Здесь чтобы работать с текстом как со списком 
    // необходимо реализовывать функции списка.
    ...
    bool empty() { return _text.empty(); }
    ...
};

Может как-то можно напрямую?
Re[2]: Наследовать stl::list<T> as string<T>
От: rg45 СССР  
Дата: 27.11.22 00:47
Оценка:
Здравствуйте, Su34, Вы писали:

S>Хочу пояснить условие задачи:

S>
 template <class T> class basic_text
S>{
S>    typedef list<string<T>> text_t;
S>    text_t    _text;
S>    // Здесь чтобы работать с текстом как со списком 
S>    // необходимо реализовывать функции списка.
S>    ...
S>    bool empty() { return _text.empty(); }
S>    ...
S>};

S>Может как-то можно напрямую?

Ну так вот здесь
Автор: rg45
Дата: 27.11.22
именно это и сделано. Шаблонный тип list_of_string полностью включает в себя всю функциональность std::list, в обоих приведенных вариантах. Ниже пример использования:

http://coliru.stacked-crooked.com/a/0a502f2fd4bc7737

#include <iostream>
#include <list>
#include <string>

#if 10
// вариант 1: с наследованием
template <typename T>
struct list_of_string : std::list<std::basic_string<T>>
{
  using list = std::list<std::basic_string<T>>; // injected name
  using list::list;                             // using basic constructors
};
#else
// вариант 2: алиас шаблонна
template <typename T>
using list_of_string = std::list<std::basic_string<T>>;
#endif

int main()
{
  const list_of_string<char> list { "one", "two", "three" };

  if (!list.empty())
  {
    for (const auto& s : list)
    {
      std::cout << s << std::endl;
    }
  }
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Наследовать stl::list<T> as string<T>
От: Su34 Россия  
Дата: 27.11.22 09:21
Оценка:
Здравствуйте, rg45, Вы писали:

R>#if 10

R>// вариант 1: с наследованием
R>template <typename T>
R>struct list_of_string : std::list<std::basic_string<T>>
R>{
R> using list = std::list<std::basic_string<T>>; // injected name
R> using list::list; // using basic constructors
R>};
R>#else
R>// вариант 2: алиас шаблонна
R>template <typename T>
R>using list_of_string = std::list<std::basic_string<T>>;
R>#endif
Далее вроде бы логично:
template <class T>
class basic_text : public std::list<T>
{
};
template <class T>
using list_of_string = basic_text<std::basic_string<T>>;

А нет!
Re[4]: Наследовать stl::list<T> as string<T>
От: rg45 СССР  
Дата: 27.11.22 10:38
Оценка:
Здравствуйте, Su34, Вы писали:

S>Далее вроде бы логично:

S>
template <class T>
S>class basic_text : public std::list<T>
S>{
S>};
S>template <class T>
S>using list_of_string = basic_text<std::basic_string<T>>;
S>

S>А нет!

Что именно "нет"? Я же дал ссылку на работающий пример, который компилируется и запускается на выполнение и работает.

А так, как вы определили шаблонный класс basic_text, конечно, полноценно работать не будет, хотя бы из-за отсутствия необходимого набора конструкторов.

Вы обратите внимание на директивы "using" в моем примере, они же не просто так там написаны. Если вы добавите такие же объявления в своем классе, то у вас тоже все заработает:

template <class T>
class basic_text : public std::list<T>
{
  using list = std::list<T>;
  using list::list;
};
template <class T>
using list_of_string = basic_text<std::basic_string<T>>;


Только я не очень понимаю, зачем вам вообще нужен этот basic_text, если вместо него вы можете использовать непосредственно std::list:

template <class T>
using list_of_string = std::list<std::basic_string<T>>;


Вот еще раз тот же пример, только без уже без лишних вариантов: http://coliru.stacked-crooked.com/a/0240d97c3a25f5af
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 27.11.2022 11:15 rg45 . Предыдущая версия . Еще …
Отредактировано 27.11.2022 10:46 rg45 . Предыдущая версия .
Re[4]: Наследовать stl::list<T> as string<T>
От: Su34 Россия  
Дата: 27.11.22 11:20
Оценка:
Здравствуйте, rg45, Вы писали:
R>template <class T>
R>class basic_text : public std::list<T>
R>{
R>  using list::list;
R>  using list = std::list<T>;
R>};
R>template <class T>
R>using list_of_string = basic_text<std::basic_string<T>>;

Спасибо, работает!
Я правда не совсем понимаю значимость
using list::list;
using list = std::list<T>;
но эта тема дополнительных познаний!
А насчет зачем нужен basic_text, согласитесь basic_text::load(szFlie) выглядит эстетичнее чем void load(std::list &list, const char* szFile) !!!
Re[5]: Наследовать stl::list<T> as string<T>
От: rg45 СССР  
Дата: 27.11.22 11:33
Оценка:
Здравствуйте, Su34, Вы писали:

S>Здравствуйте, rg45, Вы писали:

S>
R>template <class T>
R>>class basic_text : public std::list<T>
R>>{
R>>  using list::list;
R>>  using list = std::list<T>;
R>>};
R>>template <class T>
R>>using list_of_string = basic_text<std::basic_string<T>>;


S>Спасибо, работает!


Это значит, что у вас не самый новый компилятор. Не следовало менять using-объявления местами, на современных компиляторах в этом порядке не скомпилируется. Ну и спецификацию public для этих объявлений лучше указать явно, раз уж вы заменили "struct" на "class".

S>А насчет зачем нужен basic_text, согласитесь basic_text::load(szFlie) выглядит эстетичнее чем void load(std::list &list, const char* szFile) !!!


На самом деле, если написать выражения правильно, то разница между вариантами мизерная:

  text.load(szFile);
  load(text, szFile);

Только второй вариант лучше заточен для обобщенного программирования. Ну да ладно, речь же сейчас не об этом.

Для вас в таком случае определение list_of_string является лишним, можно все сделать сразу в определении basic_text. Зачем же плодить лишние имена?

http://coliru.stacked-crooked.com/a/221c3d39454a6edc

#include <iostream>
#include <list>
#include <string>

template <class T>
class basic_text : public std::list<std::basic_string<T>>
{
public:
  using list = std::list<std::basic_string<T>>;
  using list::list;
};

int main()
{
  const basic_text<char> list { "one", "two", "three" };

  if (!list.empty())
  {
    for (const auto& s : list)
    {
      std::cout << s << std::endl;
    }
  }
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 27.11.2022 11:52 rg45 . Предыдущая версия . Еще …
Отредактировано 27.11.2022 11:51 rg45 . Предыдущая версия .
Отредактировано 27.11.2022 11:38 rg45 . Предыдущая версия .
Re[5]: Наследовать stl::list<T> as string<T>
От: rg45 СССР  
Дата: 27.11.22 13:16
Оценка:
Здравствуйте, Su34, Вы писали:

S>Я правда не совсем понимаю значимость

S>using list::list;
S>using list = std::list<T>;

S>но эта тема дополнительных познаний!

Тут все просто, только вы напрасно поменяли эти объявления местами. Нужно вот так:

template <class T>
class basic_text : public std::list<std::basic_string<T>>
{
public:    
  using list = std::list<std::basic_string<T>>;
  using list::list;
};


Первое объявление: using list = std::list<std::basic_string<T>> вносит имя базового класса list в пространство имен производного класса basic_text. Для нешаблонных базовых классов (точнее, для базовых классов, не зависящих от параметров шаблона), такое действие выполняется автоматически. В этом же случае это имеет смысл сделать руками.

Второе объявление: using list::list обеспечивает использование всех конструкторов базового класса list в производном классе basic_text. Остальные функции-члены наследуются автоматически. В результате все то, что есть в базовом классе, становится доступным и в производном, ничего не нужно писать повторно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 27.11.2022 13:17 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.