简体   繁体   中英

The using declaration and function default arguments

According to the C++ 17 Standard (10.3.3 The using declaration)

1 Each using-declarator in a using-declaration98 introduces a set of declarations into the declarative region in which the using-declaration appears.

and

10 A using-declaration is a declaration and can therefore be used repeatedly where (and only where) multiple declarations are allowed.

and (The C++ 17 Standard, 11.3.6 Default arguments)

  1. ...When a declaration of a function is introduced by way of a using-declaration (10.3.3), any default argument information associated with the declaration is made known as well. If the function is redeclared thereafter in the namespace with additional default arguments, the additional arguments are also known at any point following the redeclaration where the using-declaration is in scope.

So this program

#include <iostream>

void f( int x, int y = 20 )
{
    std::cout << "x = " << x << ", y = " << y << '\n';
}

int main() 
{
    using ::f;
    void f( int, int );
    
    f( 10 );
    
    return 0;
}

as expected compiles and outputs

x = 10, y = 20

In fact it is similar to the program

#include <iostream>

void f( int x, int y )
{
    std::cout << "x = " << x << ", y = " << y << '\n';
}

int main() 
{
    void f( int, int = 20 );
    void f( int, int );
    
    f( 10 );
    
    return 0;
}

Now it would be logical consistent that the following program also was valid.

#include <iostream>

void f( int x, int y = 20 )
{
    std::cout << "x = " << x << ", y = " << y << '\n';
}

int main() 
{
    using ::f;
    
    void f( int, int );

    f( 10 );
    
    void f( int = 10, int );
    
    f();
    
    return 0;
}

However this program does not compile.

On the other hand, consider the following program.

#include <iostream>

namespace N
{
    int a = 10;
    int b = 20;
    
    void f( int, int = b );
}

int a = 30;
int b = 40;

void N::f( int x = a, int y )
{
    std::cout << "x = " << x << ", y = " << y << '\n';
}

int main() 
{
    using N::f;
    
    f();
    
    return 0;
}

It compiles successfully and its output is

x = 10, y = 20

So could be the same principles applied to functions introduced by the using declaration?

What is the reason of that such an addition of default arguments is not allowed?

You can only declare new default arguments in the same scope as the original declaration. using does not change this.

For non-template functions, default arguments can be added in later declarations of a function in the same scope.

dcl.fct.default/4

I believe

any default argument information associated with the declaration is made known as well

doesn't mean the arguments are actually imported into the scope, it's just known that they do exist and can be used.

That would mean that void f( int = 10, int ); isn't adding to void f( int x, int y = 20 ) , but is instead trying to add to void f( int, int ); which would be illegal as there isn't a default argument for the second parameter in the scope that the using declaration is in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM