Использование и злоупотребление std::visitC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Использование и злоупотребление std::visit

Сообщение Anonymous »

В последнее время я активно использую шаблон посетителя в своем коде. Я привык к классическому способу реализации, но поскольку у нас есть функциональность std::variant из C++ 17, я склонен использовать std::visit вместе с вариантом, чтобы реализовать шаблон посетителя. Однако есть ограничения, которые я обнаружил при использовании функции std::visit.
Я понимаю, что std::visit использует лямбда-выражение или структуру/класс, реализующую каждый отдельный элемент. из списка типов вариантов. Однако мое наблюдение заключается в том, что когда я реализую класс с иерархией, а родительский класс реализует перегрузки оператора(), а дочерний объект вызывает его. Оно работает!. Однако если я реализую дополнительные перегрузки оператора() в дочернем классе, который не имеет никакого отношения к типам вариантов. Код ломается и выдает ошибку, сообщающую, что std::visit требует, чтобы посетитель был исчерпывающим.
`

Код: Выделить всё

#include 
#include 
#include 
#include 

using TYPE = std::variant;
class parentVisitor {
public:
parentVisitor() = default;
std::string operator()(const int value) const {return std::to_string(value);}
std::string operator()(const double value) const {return std::to_string(value);}
std::string operator()(const float value) const {return std::to_string(value);}
std::string operator()(std::string value) const {return value;}
std::string operator()(std::monostate) const {return "";}
};

class childVisitor : public parentVisitor {
private:
TYPE m_value;
public:

// The below line creates the error!
void operator()(std::vector value) const {}

explicit childVisitor(TYPE value) : m_value(std::move(value)) {};

void printValue() {
const std::string text = std::visit(*this, m_value);
std::cout 
error: static assertion failed due to requirement 'is_invocable_v': `std::visit` requires the visitor to be exhaustive.
611 |     static_assert(is_invocable_v, "`std::visit` requires the visitor to be exhaustive.");
Я думаю, что целью std::visit является использование лямбда-функции или структуры/класса с иерархией, реализующей уникальные перегрузки оператора().
Но давайте попробуем злоупотребить std::visit, реализовав функцию в родительском классе, которую можно будет вызывать из дочернего класса, что будет применять шаблон посетителя.
`
#include
#include
#include
#include

using TYPE = std::variant;
class parentVisitor {
public:
parentVisitor() = default;
std::string operator()(const int value) const {return std::to_string(value);}
std::string operator()(const double value) const {return std::to_string(value);}
std::string operator()(const float value) const {return std::to_string(value);}
std::string operator()(std::string value) const {return value;}
std::string operator()(std::monostate) const {return "";}

std::string visit_parent(TYPE type) {
return std::visit(*this, type);
}

};

class childVisitor : public parentVisitor {
private:
TYPE m_value;
public:

// The below line creates the error!
void operator()(std::vector value) const {}

explicit childVisitor(TYPE value) : m_value(std::move(value)) {};

void printValue() {
//const std::string text = std::visit(*this, m_value);
std::string text = visit_parent(m_value);
std::cout
Дайте мне знать, это имеет смысл и есть ли другой способ реализации функциональности посетителей из иерархии.

Подробнее здесь: https://stackoverflow.com/questions/793 ... g-stdvisit
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»