Chapter 4 Variable Parameter Template: 4.3 Application of Variable Parameter Template

4.3 Application of Variadic Templates

4.3 Application of variable parameter templates

 

Variadic templates play an important role when implementing generic libraries, such as the C++ standard library.

Variable parameter templates play a very important role in the implementation of common libraries (such as the C ++ standard library).

One typical application is the forwarding of a variadic number of arguments of arbitrary type.

A classic application is to transmit an arbitrary number of parameters of any type.

For example, we use this feature when:

For example, we use this feature in the following situations:

• Passing arguments to the constructor of a new heap object owned by a shared pointer:

 Pass the parameters to the constructor of the new heap object owned by shared_ptr:

// create shared pointer to complex<float> initialized by 4.2 and 7.7:
auto sp = std::make_shared<std::complex<float>>(4.2, 7.7);

• Passing arguments to a thread, which is started by the library:

  Pass parameters to the thread object started by the standard library.

std::thread t (foo, 42, "hello"); //call foo(42,"hello") in a separate thread

• Passing arguments to the constructor of a new element pushed into a vector:

  Pass the parameters to the constructor of the newly pushed element in the vector:

std::vector<Customer> v;
…
v.emplace("Tim", "Jovi", 1962); //insert a Customer initialized by three arguments

Usually, the arguments are “perfectly forwarded” with move semantics (see Section 6.1 on page 91), so that the corresponding declarations are, for example:

Normally, these parameters are "perfectly forwarded" through mobile semantics (see section 6.1 on page 91), so the corresponding declaration is as follows:

namespace std {
    template<typename T, typename... Args> shared_ptr<T> make_shared(Args&& … args);

    class thread {
    public:
        template<typename F, typename... Args>
        explicit thread(F&& f, Args&& … args);
        ...
    };

    template<typename T, typename Allocator = allocator<T>>
    class vector {
    public:
        template<typename... Args> reference emplace_back(Args&& …
            args);
        ...
    };
}

Note also that the same rules apply to variadic function template parameters as for ordinary parameters. For example, if passed by value, arguments are copied and decay (e.g., arrays become pointers), while if passed by reference, parameters refer to the original parameter and don’t decay:

Also note that the same rules apply to variable function template parameters as with ordinary parameters. For example, if passed by value, the parameters are copied and the type is degraded (eg, the array becomes a pointer). If passed by reference, the parameter will refer to the original parameter and the type will not degenerate (decay).

// args are copies with decayed types: (args is a copy of the degraded parameters) 
template <typename ... Args> void foo (Args ... args); 

// args are nondecayed references to passed objects: (args are not degraded, they are passed Into the object reference) 
template <typename… Args> void bar (Args const &… args);

 

Guess you like

Origin www.cnblogs.com/5iedu/p/12727449.html