What is the name of this unusual C++ template feature used by Boost.Spirit?

Barrett Adair picture Barrett Adair · Aug 31, 2016 · Viewed 8.6k times · Source

The code below is from the Boost.Spirit x3 documentation. It uses an interesting C++ syntax that I've never seen before, which is nearly impossible to describe in a search query without knowing the proper terminology. Is this shorthand for the forward declaration of a class? Where is this feature mentioned in the C++ standard?

namespace parser
{
    using x3::eps;
    using x3::lit;
    using x3::_val;
    using x3::_attr;
    using ascii::char_;

    auto set_zero = [&](auto& ctx){ _val(ctx) = 0; };
    auto add1000 = [&](auto& ctx){ _val(ctx) += 1000; };
    auto add = [&](auto& ctx){ _val(ctx) += _attr(ctx); };

    // What is this? This is the very first use of the identifier `roman`.
    x3::rule<class roman, unsigned> const roman = "roman";
    //       ^^^^^^^^^^^

    auto const roman_def =
        eps                 [set_zero]
        >>
        (
            -(+lit('M')     [add1000])
            >>  -hundreds   [add]
            >>  -tens       [add]
            >>  -ones       [add]
        )
    ;

    BOOST_SPIRIT_DEFINE(roman);
}

Answer

Robert Pr&#233;vost picture Robert Prévost · Aug 31, 2016

The arguments to a template do not necessarily have to be defined to be used. The use of "class roman" actually declares the class roman.

Here is some example code:

#include <iostream>
template <class T> void foo();
template<> void foo<class roman>()
{
    // allowed because roman is declared
    roman* pointer1;
    // not allowed because romania is not declared
    // romania* pointer2;
    std::cout << "Hello world!" << std::endl;
    return;
}
int main(int argc, char** argv) {
    return 0;
}

As people have pointed out in the comments above, this distinguishes this instantiation of the template. And to directly answer the question you had, specifying the nature of the template argument in a template instantiation is called an 'elaborated type specifier'.