Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > no match for ternary 'operator?:'


Автор: Fynivx 16.3.2012, 19:03
Здравствуйте. У меня следующая проблема:
EventEmitter.h++:
Код

namespace Native {
template <
    typename EventListener  = DefaultListener,
    typename EventMessage   = DefaultMessage
>
class EventEmitter {
public:
//...
    void on ( std::string& event_name, EventListener& listener );
//...
private:
//...
    std::timed_mutex    locker;
    std::atomic_bool    change; // если проходит изменение списка событий, хранит true
};

EventEmitter.c++:
Код

template < typename EventListener, typename EventMessage >
void EventEmitter< EventListener, EventMessage >::on ( std::string& event_name, EventListener& listener ) {
    std::unique_lock<std::timed_mutex> map_locked(
        locker,
        change.load(  ) ?
            std::chrono::seconds( 1 ) : // если в списке событий проходят изменения, нужно обязательно дождаться разблокировки
            std::defer_lock // если нет, блокировка может быть у любого другого статического метода - позже вызывается try_lock.
        // ^--- тут выскакивает ошибка
    );
//...
}

change.load(  )  возвращает bool.

Ошибка следующая:
Цитата
/home/fynivx/Projects/Muse/Sources/Engine/EventEmitter.c++:72:9: error: no match for ternary ‘operator?:’ in ‘((Native::EventEmitter<EventListener, EventMessage>*)this)->Native::EventEmitter<EventListener, EventMessage>::change.std::atomic_bool::load() ? (std::chrono::seconds)(1) : std::defer_lock’


Собственно, вопрос: как от нее избавиться?

Я догадываюсь, что это может быть из-за того, что, кажется, std::chrono::seconds - класс со статическим оператором (). Но от этого не легче. Да это и не факт.
Или это из-за того, что std::chrono::seconds(1) и std::defer_lock разных типов?

Как это вылечить?

Жду вашей помощи. Заранее спасибо.

Автор: volatile 17.3.2012, 00:08
Цитата(Fynivx @  16.3.2012,  19:03 Найти цитируемый пост)
Я догадываюсь, что это может быть из-за того, что, кажется, std::chrono::seconds - класс со статическим оператором (). 
Нет, здесь это не причем.

Цитата(Fynivx @  16.3.2012,  19:03 Найти цитируемый пост)
Или это из-за того, что std::chrono::seconds(1) и std::defer_lock разных типов?

Угу, это же тернарный оператор. Типы должны быть приводимы.
Но здесь еще, кроме того, они вызывают разные конструкторы (там перегрузка )
Можно как-то приблизительн, так, например:
Код

std::unique_lock<std::timed_mutex> map_locked;
if (change.load ())
{
   std::unique_lock<std::timed_mutex> t (locker, std::chrono::seconds( 1 ));
   map_locked.swap (t);
}
else
{
   std::unique_lock<std::timed_mutex> t (locker, std::defer_lock);
   map_locked.swap (t);
}


Fynivx, написал чисто так, на коленке.
Так что могу ошибаться.


Автор: Fynivx 17.3.2012, 00:27
Цитата(volatile @  17.3.2012,  00:08 Найти цитируемый пост)
map_locked.swap (t);

Хм. И после обмена удалится старый, ненужный блокировщик. Кажется, так и нужно.
А я то думал, для чего может пригодиться этот swap...)
Спасибо)

Автор: volatile 17.3.2012, 01:02
можно тоже самое и с тернарным записать
Код

std::unique_lock<std::timed_mutex> map_locked;
map_locked.swap (change.load () ? std::unique_lock<std::timed_mutex> (locker, std::chrono::seconds( 1 ))
                                : std::unique_lock<std::timed_mutex> (locker, std::defer_lock) );

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)