Variadic Templates example

后端 未结 5 2173
别那么骄傲
别那么骄傲 2021-02-07 20:20

Consider following code, I don\'t understand why empty function of print must be defined.

#include 
using namespace std;

void print()
{   
}   
         


        
5条回答
  •  长情又很酷
    2021-02-07 20:55

    CORRECT WAY:

    Variadic templates is strictly related to induction, a mathematical concept.

    The compiler resolves the following function call

    print('a', 3, 4.0f);
    

    into

    std::cout<< 'a' <

    which is resolved into

    std::cout<< 'a' <

    which is resolved into

    std::cout<< 'a' <

    At this point it searches for a function overload whose match is the empty function.

    • All functions that have 1 or more arguments are matched to the variadic template
    • All functions that have no argument are matched to the empty function

    The culprit is that you must have, for every possible combination of parameters, only 1 function.


    ERROR 1:

    Doing the following would be an error

    template< typename T>
    void print( const T& arg) // first version
    {   
        cout<< arg<
    void print (const T& firstArg, const Types&... args) // second version
    {   
        cout << firstArg << endl; // print first argument
        print(args...); // call print() for remaining arguments
    }
    

    Because when you call print the compiler doesn't know which function to call.

    Does print(3) refers to "first" or "second" version? Both would be valid because the first has 1 parameter, and the second can accept one parameter too.

    print(3); // error, ambiguous, which one you want to call, the 1st or the 2nd?
    

    ERROR 2:

    The following would be an error anyway

    // No empty function
    
    template 
    void print (const T& firstArg, const Types&... args) 
    {   
        cout << firstArg << endl; // print first argument
        print(args...); // call print() for remaining arguments
    }
    

    In fact, if you use it alone without the compiler would do

     print('k', 0, 6.5);
    

    which is resolved into

     std::cout<<'k'<

    which is resolved into

     std::cout<<'k'<

    which is resolved into

     std::cout<<'k'<

    As you see in the last attempt, the compiler tries to call print() with no arguments. However if such a function does not exists it is not called, and that's why you should provide that empty function (don't worry, the compiler will optimize code so empty functions don't decrease performance).

提交回复
热议问题