Правильна ли эта реализация посетителя?

Я реализую посетителя, чтобы использовать его с библиотекой вариантов буста. Я хочу знать, правильно ли специализироваться boost::static_visitor<> с константным ссылочным типом.

Обратите внимание, что мой вопрос здесь следующий:

Есть какие-то проблемы со специализацией boost::static_visitor<> в boost::static_visitor<const T&> ?

template<typename T>
struct my_visitor : public boost::static_visitor<const T&> {

    template<typename U> const T& operator()(U& u) const {
        // some code here .....
        return X<U>::get_some_t(); // finally return some T.
    }
};

2 ответа

Решение

Нет проблем, если вы не вернете ссылку на локальную / временную ссылку.

Кроме того, обязательно проверяйте действительность ссылки во времени (она заканчивается, когда уничтожается вариантный объект, то есть когда уничтожается сам вариант, или (!), Когда он повторно инициализируется).

Предпосылки и объяснение

Вариант содержит объект "текущего" типа элемента, и вы можете ссылаться на этот объект совершенно нормально. До тех пор, пока вариант не будет повторно инициализирован для другого типа элемента (в этом случае ссылка "просто" свисает, точно так же, как если бы закончилось время жизни объекта, на который указывает ссылка).

Так что если get_somet_t() возвращает T& или же T const& (или что-то с подходящим неявным преобразованием) проблем нет.

В более простой настройке позвольте мне продемонстрировать допустимые параметры:

variant<int, std::string> v1 = 42;

int& i1 = get<int>(v1); // returns by ref, valid
i1 *= 2;

// now v1 contains the updated integer value 84

Кроме того, вы можете даже сделать варианты / просто ссылки /:

std::string s = "hello";
int answer = 42;

variant<int&, std::string&> v2(s);
get<std::string&>(v2) += " world"; // now s contains "hello world"

variant<int&, std::string&> v3(answer);
get<int&>(v3) *= 2; // now `answer` contains 84

Посмотреть все Live On Coliru


демонстрация

Иными словами, это нормально:

struct A { std::string a_property; };
struct B { std::string b_field;    };

struct select_member : static_visitor<std::string&> {
    std::string& operator()(A& a) const { return a.a_property; }
    std::string& operator()(B& b) const { return b.b_field;    }
};

int main()
{
    variant<A,B> v = A { "some string" };

    apply_visitor(select_member(), v) += " suffix";

    std::cout << get<A>(v).a_property << "\n"; // prints "some string suffix"
}

Посмотрите это в прямом эфире на Coliru.

Что насчет этого, это аккуратно?

      public interface Worker {
  <T> T accept( Visitor<T> visitor);
}

public class Developer implements Worker { 
  @Override
  public <T> T accept( Visitor<T> visitor ) {
    return visitor.workAsDeveloper( this );
  }
}

public class Manager implements Worker {
  @Override
  public <T> T accept( Visitor<T> visitor ) {
    return visitor.manageAsManager( this );
  }
}

public class Boss implements Worker {  
  @Override
  public <T> T accept( Visitor<T> visitor ) {
    return visitor.planLikeBoss( this );
  }
}

public interface Visitor<T> {
  T workAsDeveloper( Developer type );
  T manageAsManager( Manager type );
  T planLikeBoss( Boss type );
}

public class VisitorImpl implements Visitor<String> {
  
  @Override
  public String workAsDeveloper( Developer type ) {
    return "Working hard as a Developer";
  }
  
  @Override
  public String manageAsManager( Manager type ) {
    return "Managing smoothly as a Manager";
  }
  
  @Override
  public String planLikeBoss( Boss type ) {
    return "Planning like a Boss";
  }
}

public class App {
  Visitor<String> visitor;
  
  public App( Visitor<String> visitor ) {
    this.visitor = visitor;
  }
  
  public static void main( String[] args ) {
    // Given
    App app = new App( new VisitorImpl() );
    
    Developer developer = new Developer();
    Manager manager = new Manager();
    Boss boss = new Boss();
    
    // When
    app.run( developer );
    app.run( manager );
    app.run( boss );
  }
  
  void run( Worker worker ) {
    System.out.println( worker.accept( visitor ) );
  }
}
Другие вопросы по тегам