Klaus Klaus - 2 months ago 10
C++ Question

how can returning a type instead of a object be valid, misunderstanding a code fragment

I tried out boost msm lite which is a very nice state machine implementation. As always I try to understand how it is working and found a code fragment which I can't understand.

As a remark: I would not post the whole file from boost here, it is here: https://github.com/boost-experimental/msm-lite/blob/master/include/boost/msm-lite.hpp

The test code only for understanding the things behind the curtain:

auto x2 = "test"_t; //compiles fine!


That should go to this code fragment:

template <class T, T... Chrs>
auto operator""_t() BOOST_MSM_LITE_NOEXCEPT {
return event<aux::string<Chrs...>>; // ??? How this can work?
}


My (mis)understanding here is, that it will return the
type
instead of a instance of the type? But it compiles... why?

event
is defined as:

template <class>
struct event {

template <class T, BOOST_MSM_LITE_REQUIRES(concepts::callable<bool, T>::value)>
auto operator[](const T &t) const BOOST_MSM_LITE_NOEXCEPT {
return transition_eg<event, T>{*this, t};
} template <class T, BOOST_MSM_LITE_REQUIRES(concepts::callable<void, T>::value)>
auto operator/(const T &t) const BOOST_MSM_LITE_NOEXCEPT {
return transition_ea<event, T>{*this, t};
}
};


The following example compiles fine:

#include <cassert>
#include <iostream>
#include "boost/msm-lite.hpp"
namespace msm = boost::msm::lite;

int main()
{
using namespace msm;
auto x1 = "idle"_s;
auto x2 = "test"_t;
}

Answer
template <class T, T... Chrs>
auto operator""_t() BOOST_MSM_LITE_NOEXCEPT {
    return event<aux::string<Chrs...>>;       // ??? How this can work?
}

It works because this operator is not returning a type, but an instance of the template variable event, which is defined in line 1536:

template <class TEvent>
detail::event<TEvent> event{};

Template variables were only introduced in C++14, which is likely why this was harder for you to find and understand. Also note that the _s operator relies on state, which is not a template variable (thus why it has to be instantiated at the operator function).

Comments