Template template parameters and default arguments

后端 未结 2 683
灰色年华
灰色年华 2021-01-19 04:41

Consider the following code which uses \"template template\" parameters to instantiate a class template using multiple types:

#include 
using         


        
相关标签:
2条回答
  • 2021-01-19 05:06

    Default arguments are ignored for parameters of template arguments. There's this example in n3337, chapter [temp.arg.template], paragraph 2:

    template<class T> class A { /∗ ... ∗/ };
    template<class T, class U = T> class B { /∗ ... ∗/ };
    template <class ... Types> class C { /∗ ... ∗/ };
    template<template<class> class P> class X { /∗ ... ∗/ };
    template<template<class ...> class Q> class Y { /∗ ... ∗/ };
    X<A> xa; // OK
    X<B> xb; // ill-formed: default arguments for the parameters of a template argument are ignored
    X<C> xc; // ill-formed: a template parameter pack does not match a template parameter
    Y<A> ya; // OK
    Y<B> yb; // OK
    Y<C> yc; // OK
    

    Note the comment at X<B> xb; above. I can't find the normative text, I'm afraid.

    You can correlate this with functions - default arguments are not a part of a signature, either. The same thing would also happen if you tried to call a function that has a parameter defaulted through a function pointer.

    0 讨论(0)
  • 2021-01-19 05:10

    With a using template alias, a new feature in C++11, you can create a one-parameter template that is equivalent to another template that has two parameters, one of which is defaulted.

    template <E e> using Foo1 = Foo<e>;
    

    This creates Foo1, a one-parameter template, even though Foo technically has two arguments, one of which is defaulted. You can use it as:

    do_something<Foo1>(int(55));
    

    Alternatively, if C++11 features such as using are not available, then you scan specify the default in your declaration of do_something. This means then, unfortunately, that do_something can no longer deal with simple one-arg templates. Hence, I think the using method above is better.

    template <template <E, class = void> class Action, class T>
    void do_something(const T& value);
    

    If you take this approach, putting the default in the args to do_something, then this default takes precedence over the default specified at the declaration Foo. This is based on my experiments, and I can't comment with confidence on what is, and is not, standard. But I do think the using trick is fully standards-compliant regarding C++11.

    (Ubuntu clang version 3.0-6ubuntu3)

    0 讨论(0)
提交回复
热议问题