For Nested Templates, When Did '>>' Become Standard C++ (Instead of '> >')

Visual C++: Using nested templates, is it possible to mark instead of as error?

C++11 made >> to end nested templates legal. The issue is that VC++ 2010 implements (and enables unconditionally) this part of C++11, but you're using other compilers which either don't implement this in the version you're targeting or you haven't enabled their C++11 mode.

VC++ doesn't support modes and instead simply enables bits and pieces of language specs as they get around to implementing them. So your solution is to either downgrade the VC++ compiler to a version that doesn't enable this feature, or upgrade or enable C++11 on the other compilers you're targeting so that this is not an error.


If you can't do either of those, and if you're not already using an automated build system then you can set one up to help catch these compatibilities errors faster than you currently are. Configure one so that as soon as any team member commits new code the code is checked on all the platforms you support.

Automated build systems often also allow users to provide code changes to be checked on all the build slaves directly from the team member's working directory, instead of requiring the code to be committed to the shared repo first. Setting this up is just about as good as having the initial development occur directly on each supported platform.

Template issue with vector

They aren't identical (at least prior to C++11) because the last >> characters are parsed as a single operator (operator>>). Putting a space between them causes the expected behavior.

The same situation happens where the compiler parses <: as the beginning of a tigraph/digraph. For example:

N<::T> // <: parsed as [

A space separating the operators causes the code to work fine.

Template within template: why ` ' should be ` ' within a nested template argument list

Sometimes you want it to be >>. Consider

boost::array<int, 1024>>2> x;

In C++03 this successfully parses and creates an array of size 256.

C++ Templates Angle Brackets Pitfall - What is the C++11 fix?

It's fixed by adding a special case to the parsing rules when parsing template arguments.

C++11 14.2/3: When parsing a template-argument-list, the first non-nested > is taken as the ending delimiter rather than a greater-than operator. Similarly, the first non-nested >> is treated as two consecutive but distinct > tokens, the first of which is taken as the end of the template-argument-list and completes the template-id.

How do nested templates get resolved in C++?

You have to take in count that there are three types of template parameters:

1) types

2) non-types (or values)

3) template-templates

The first type is preceded by typename (or class)

template <typename T>
void foo (T const & t);

In the preceding example, T is a type and t (a classical function argument) is a value of type T.

The second type of template parameter are values and are preceded by the type of the value (or auto, starting from C++17, for a not specified type)

template <int I>
void bar ()
{ std::cout << I << std::endl; }

In the preceding example the I template parameter is a value of type int.

The third type is the most complex to explain.

Do you know (I suppose) that std::vector<int> and std::vector<double> are different types, but they have in common std::vector, a template class.

A template-template parameter is a parameter that accept std::vector, the template class without arguments.

A template-template parameter is preceded by a template keyword, as in the following example

template <template <int> class C>
void baz ();

The template-template parameter C in the preceding example is class (or struct) that require a single int (value) template parameter.

So if you have a class

template <int I>
class getInt
{ };

you can pass getInt, as template parameter, to baz()

baz<getInt>();

Now you should be able to understand your code:

template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

the is_specialization struct is a template struct that receive, as template parameters, a type (T) and a template-template Template that accept classes/structs receiving a variadic number of type template parameters.

Now you have a specialization of is_specialization:

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};

This specialization is selected when the first template parameter (Template<Args...>) is a class based on the second (Template).

An example: if you instantiate

is_specialization<std::vector<int>, std::map>

the main version (that inherit from std::false_type) is selected because std::vector<int> isn't based on std::map.

But if you instantiate

is_specialization<std::vector<int>, std::vector>

the specialization (that inherit from std::true_type) is selected because std::vector<int> is based on std::vector.

Double closing angle brackets ( ) generate syntax error in SPECIFIC case

You have used a pre c++11 standard compiler. The older standard had a problem letting the parser disambiguate a pair of closing angle brackets >> used in a nested template type specifier, from the operator>>(). Thus you had to write a space between them.

The samples like >>> or >>* are falling under a different case for the old parsers, thus they work without error message.


I have to admit, I don't actually know what exactly was done in the c++11 (the current) standards definitions, that this situation can be clearly disambiguated by a c++11 compliant parser.

Nested templates vs shift operator

MSVC++2010 supports C++0x feature Right Angle Brackets

When did template template parameters become part of the standard?

Most likely since the first standard, C++98. It is in C++03 14.3.3 Template template arguments, and I doubt such a large change would have been introduced in what is essentially a revision of C++98. The same section is present in copies of the C++98 standard, although I cannot vouch for their authenticity. The ISO standard document itself has been withdrawn.

How to instantiate, by the standard, a class template containing nested subclass templates

There's a few things going wrong here:

template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10;
};

MyData is an incomplete type here, so we can't use it just yet in that way. However, since Item1 is inherited from Data<C>, we should be able to just refer to it directly:

Data<C>::Item1<int> item10;

But now, Data<C>::Item1 is a dependant type, so we need to use typename to tell the compiler that it is, in fact, a type:

typename Data<C>::Item1<int> item10;

Finally, because Item1 is a template member of a dependant type, we also need to tell the compiler that it is a template (as opposed to a constant or something).

typename Data<C>::Item1 template<int> item10;

So at the end, we land at:

template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};

template <class C>
struct MyData : Data<C> {
typename Data<C>::template Item1<int> item10;
};

struct S;

MyData<S> dataS;


Related Topics



Leave a reply



Submit