C++17 Early Adopters: variable-length using declarations

Source: Internet
Author: User

Using declarations

First look at the application of the using declaration in the class:

Code 1

#include <iostream>using namespace std;struct A {    void f(int) {cout << "A::f(int)" << endl;}};struct S : A {};int main(){    S s;    s.f(1); // A::f(int)}
    • Class S inherits the member function F of Class A, so the instance s of class s calls the F output to A::f

Code 2

#include <iostream>using namespace std;struct A {    void f(int) {cout << "A::f(int)" << endl;}};struct S : A {    void f(double) {cout << "S::f(double)" << endl;}};int main(){    S s;    s.f(1); // S::f(double)}
    • Class S inherits the member function F of Class A, and the class S also defines the member function f
    • The member function F of class s obscures the function f of the same name in the base class, so the instance s of S calls the F output to S::f

Code 3

#include <iostream>using namespace std;struct A {    void f(int) {cout << "A::f(int)" << endl;}};struct S : A {    using A::f;    void f(double) {cout << "S::f(double)" << endl;}};int main(){    S s;    s.f(1); // A::f(int)}
    • Class S inherits the member function F of Class A, and the class S also defines the member function f
    • Class S introduces the member function F of base class A into its own scope through a using declaration. The member function F of Class S forms an overloaded relationship with a function of the same name as the base class A.
    • parameter is integer, so s instance s calls F output to A::f

Code 4

#include <iostream>using namespace std;struct A {    void f(int) {cout << "A::f(int)" << endl;}};struct B {    void f(double) {cout << "S::f(double)" << endl;}};struct S : A, B {};int main(){    S s;    s.f(1); // compile error}
    • Class S also inherits the member function F of Class A and Class B, both of which form a competitive relationship.
    • The compiler cannot tell if the instance s of S is calling the member function f from class A or class B, so there is a compilation error.

Code 5

#include <iostream>using namespace std;struct A {    void f(int) {cout << "A::f(int)" << endl;}};struct B {    void f(double) {cout << "S::f(double)" << endl;}};struct S : A, B {    using A::f;    using B::f;};int main(){    S s;    s.f(1); // A::f(int)}
    • Class S inherits the member function F of Class A and class B at the same time.
    • Class S introduces the member function F of base class A and base class B to its own scope through a using declaration. A function with the same name as the base class A and base class B forms an overloaded relationship in class S.
    • parameter is integer, so s instance s calls F output to A::f
Using declarations for C++17

Multiple using declarations in C++17 can be concatenated by commas.

Code 6

#include <iostream>using namespace std;struct A {    void f(int) {cout << "A::f(int)" << endl;}};struct B {    void f(double) {cout << "S::f(double)" << endl;}};struct S : A, B {    using A::f, B::f; // C++17};int main(){    S s;    s.f(1); // A::f(int)}
C++17 variable-length using declaration

By using the Add ... Using declaration, you can convert a using declaration in a variable-length template parameter type to multiple variable-length using declarations that are synthesized with commas.

#include <iostream>#include <string>using namespace std;template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;int main(){    overloaded s{        [](int){cout << "int" << endl;},        [](double){cout << "double" << endl;},        [](string){cout << "string" << endl;},    };    s(1); // int    s(1.); // double    s("1"); // string}
  • template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
    This is a declaration of a template class.
  • template<class... Ts>: the template parameter for the overloaded class is a variable-length parameter pack Ts.
    Suppose Ts contains T1, T2, ..., TN, then this statement can be expanded to:template<class T1, class T2, ..., class TN>
  • struct overloaded : Ts...: The base class of the overloaded class is all parameter types within the parameter pack Ts.
    Suppose Ts contains T1, T2, ..., TN, then this statement can be expanded to:struct overloaded : T1, T2, ..., TN
  • using Ts::operator()...;: This is a variable-length using declaration.
    Suppose Ts contains T1, T2, ..., TN, then this statement can be expanded to:using T1::operator(), T1::operator(), ..., TN::operator(), ;
    That is, the base class of the overloaded class, which is the function call operator of all parameter types within the parameter package Ts, is introduced into its own scope by the overloaded class.
  • Template<class ... Ts> overloaded (Ts ...)-overloaded<ts ...
    This is an auto-inference wizard that helps the compiler derive overloaded template parameter types based on the type of the overloaded constructor parameter.
    This auto-inference wizard tells the compiler that if the overloaded constructor has a set of types for all parameters of TS, then the overloaded template parameter type is all the types that TS contains.
    that is, if the expression A1, A2, ..., the type of an IS T1, T2, ..., TN,
    then the type of the constructor expression overloaded {A1, A2, ..., an} is the ov ERLOADED<T1, T2, ..., Tn> .
    * overloaded s{
    [] (int) {cout << "int" << Endl;},
    [] (double) { cout << "Double" << Endl;},
    [] (string) {cout << "string" << Endl;},
    code>}; The constructor for instance s of the
    overloaded class contains 3 lambda parameters, or it can be thought of as 3 function objects that each contain a operator ().
    based on the definition of the overloaded class, the S object inherits the operator () of the 3 lambda (function objects), meaning that the 3 lambda operator (), the function body, forms an overloaded relationship inside the S object.
    based on the overloaded class's Auto-Inference wizard, the S object is of type overloaded<t1, T2, T3> , where T1, T2, and T3 are the types of 3 lambda parameters.
  • By taking advantage of the C++17 's new feature-long using declaration and the Auto-Inference wizard, an instance of the overloaded class can easily and subtly synthesize multiple lambda functions into a large function object with multiple overloaded operator ().
  • Overloaded this template class is so useful and the implementation mechanism is so complex that it should be included in the standard library as soon as possible.

C++17 Early Adopters: variable-length using declarations

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.