Why does C++ allow unnamed function parameters?












25















The following is a perfectly legal C++ code



void foo (int) {
cout << "Yo!" << endl;
}

int main (int argc, char const *argv) {
foo(5);
return 0;
}


I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.



Why is this legal to begin with?










share|improve this question

























  • The only place I've ever seen it actually used is for prototypes; I've seen some function prototypes and class definitions that omitted the parameter names for brevity or other reasons. I'm not sure why it's legal.

    – Wug
    Aug 29 '12 at 21:25






  • 2





    One standard use case is in Tag Dispatching

    – Edvard Fagerholm
    Jul 14 '15 at 11:10
















25















The following is a perfectly legal C++ code



void foo (int) {
cout << "Yo!" << endl;
}

int main (int argc, char const *argv) {
foo(5);
return 0;
}


I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.



Why is this legal to begin with?










share|improve this question

























  • The only place I've ever seen it actually used is for prototypes; I've seen some function prototypes and class definitions that omitted the parameter names for brevity or other reasons. I'm not sure why it's legal.

    – Wug
    Aug 29 '12 at 21:25






  • 2





    One standard use case is in Tag Dispatching

    – Edvard Fagerholm
    Jul 14 '15 at 11:10














25












25








25


10






The following is a perfectly legal C++ code



void foo (int) {
cout << "Yo!" << endl;
}

int main (int argc, char const *argv) {
foo(5);
return 0;
}


I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.



Why is this legal to begin with?










share|improve this question
















The following is a perfectly legal C++ code



void foo (int) {
cout << "Yo!" << endl;
}

int main (int argc, char const *argv) {
foo(5);
return 0;
}


I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.



Why is this legal to begin with?







c++ function parameters






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 23 '18 at 2:35









Peter Ruderman

10.2k2352




10.2k2352










asked Aug 29 '12 at 21:21









JAMJAM

35.2k117279432




35.2k117279432













  • The only place I've ever seen it actually used is for prototypes; I've seen some function prototypes and class definitions that omitted the parameter names for brevity or other reasons. I'm not sure why it's legal.

    – Wug
    Aug 29 '12 at 21:25






  • 2





    One standard use case is in Tag Dispatching

    – Edvard Fagerholm
    Jul 14 '15 at 11:10



















  • The only place I've ever seen it actually used is for prototypes; I've seen some function prototypes and class definitions that omitted the parameter names for brevity or other reasons. I'm not sure why it's legal.

    – Wug
    Aug 29 '12 at 21:25






  • 2





    One standard use case is in Tag Dispatching

    – Edvard Fagerholm
    Jul 14 '15 at 11:10

















The only place I've ever seen it actually used is for prototypes; I've seen some function prototypes and class definitions that omitted the parameter names for brevity or other reasons. I'm not sure why it's legal.

– Wug
Aug 29 '12 at 21:25





The only place I've ever seen it actually used is for prototypes; I've seen some function prototypes and class definitions that omitted the parameter names for brevity or other reasons. I'm not sure why it's legal.

– Wug
Aug 29 '12 at 21:25




2




2





One standard use case is in Tag Dispatching

– Edvard Fagerholm
Jul 14 '15 at 11:10





One standard use case is in Tag Dispatching

– Edvard Fagerholm
Jul 14 '15 at 11:10












4 Answers
4






active

oldest

votes


















34














Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.



The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).



There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.






share|improve this answer





















  • 3





    ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

    – Aasmund Eldhuset
    Aug 29 '12 at 21:25








  • 1





    Can't unused parameters also be used for function overloading purposes?

    – Lily Ballard
    Aug 29 '12 at 21:34






  • 1





    @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

    – dasblinkenlight
    Aug 29 '12 at 21:37






  • 2





    @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

    – Lily Ballard
    Aug 29 '12 at 21:41






  • 7





    Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

    – Roddy
    Aug 29 '12 at 22:39



















10














Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.



This may happen for example for a method in a derived class, for a callback function or for a template parameter.



Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.






share|improve this answer































    0














    Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".



    It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.



    It's used like this:



    class Friendly; // Just a forward declaration

    class Key {
    private:
    Key() {}
    friend class Friendly;
    };

    class Safe() {
    public:
    static int locked(Key, int i) {
    // Do something with `i`,
    // but the key is never used.
    return i;
    }
    private:
    static void inaccessible() {}
    };

    class Friendly {
    public:
    void foo() {
    int i = Safe::locked(Key(), 1); // OK
    int j = Safe::locked({}, 2); // OK, sice C++11
    }
    void bar() {
    Safe::inaccessible(); // Not OK, its inaccessible
    }
    };

    int i = Safe::locked(3); // Not OK, wrong parameters
    int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
    int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly





    share|improve this answer

































      -2














      I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.



      // named-reference.cpp  
      // Compile with: /EHsc
      #include <iostream>
      using namespace std;

      // A class that contains a memory resource.
      class MemoryBlock
      {
      // TODO: Add resources for the class here.
      };

      void g(const MemoryBlock&)
      {
      cout << "In g(const MemoryBlock&)." << endl;
      }

      void g(MemoryBlock&&)
      {
      cout << "In g(MemoryBlock&&)." << endl;
      }

      MemoryBlock&& f(MemoryBlock&& block)
      {
      g(block);
      return block;
      }

      int main()
      {
      g(f(MemoryBlock()));
      }


      This example produces the following output:




      In g(const MemoryBlock&).

      In g(MemoryBlock&&).




      In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).






      share|improve this answer
























      • This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

        – Imad Nabil Alnatsheh
        May 1 '17 at 22:41











      • This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

        – underscore_d
        May 20 '17 at 12:06













      • This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

        – M.M
        Oct 23 '18 at 2:31











      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12186698%2fwhy-does-c-allow-unnamed-function-parameters%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      34














      Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.



      The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).



      There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.






      share|improve this answer





















      • 3





        ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

        – Aasmund Eldhuset
        Aug 29 '12 at 21:25








      • 1





        Can't unused parameters also be used for function overloading purposes?

        – Lily Ballard
        Aug 29 '12 at 21:34






      • 1





        @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

        – dasblinkenlight
        Aug 29 '12 at 21:37






      • 2





        @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

        – Lily Ballard
        Aug 29 '12 at 21:41






      • 7





        Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

        – Roddy
        Aug 29 '12 at 22:39
















      34














      Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.



      The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).



      There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.






      share|improve this answer





















      • 3





        ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

        – Aasmund Eldhuset
        Aug 29 '12 at 21:25








      • 1





        Can't unused parameters also be used for function overloading purposes?

        – Lily Ballard
        Aug 29 '12 at 21:34






      • 1





        @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

        – dasblinkenlight
        Aug 29 '12 at 21:37






      • 2





        @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

        – Lily Ballard
        Aug 29 '12 at 21:41






      • 7





        Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

        – Roddy
        Aug 29 '12 at 22:39














      34












      34








      34







      Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.



      The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).



      There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.






      share|improve this answer















      Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.



      The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).



      There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 23 '17 at 12:18









      Community

      11




      11










      answered Aug 29 '12 at 21:24









      dasblinkenlightdasblinkenlight

      615k617861205




      615k617861205








      • 3





        ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

        – Aasmund Eldhuset
        Aug 29 '12 at 21:25








      • 1





        Can't unused parameters also be used for function overloading purposes?

        – Lily Ballard
        Aug 29 '12 at 21:34






      • 1





        @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

        – dasblinkenlight
        Aug 29 '12 at 21:37






      • 2





        @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

        – Lily Ballard
        Aug 29 '12 at 21:41






      • 7





        Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

        – Roddy
        Aug 29 '12 at 22:39














      • 3





        ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

        – Aasmund Eldhuset
        Aug 29 '12 at 21:25








      • 1





        Can't unused parameters also be used for function overloading purposes?

        – Lily Ballard
        Aug 29 '12 at 21:34






      • 1





        @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

        – dasblinkenlight
        Aug 29 '12 at 21:37






      • 2





        @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

        – Lily Ballard
        Aug 29 '12 at 21:41






      • 7





        Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

        – Roddy
        Aug 29 '12 at 22:39








      3




      3





      ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

      – Aasmund Eldhuset
      Aug 29 '12 at 21:25







      ...or for regular functions that are to be used as a callback (and therefore must conform to a given signature) but don't need to use the parameter.

      – Aasmund Eldhuset
      Aug 29 '12 at 21:25






      1




      1





      Can't unused parameters also be used for function overloading purposes?

      – Lily Ballard
      Aug 29 '12 at 21:34





      Can't unused parameters also be used for function overloading purposes?

      – Lily Ballard
      Aug 29 '12 at 21:34




      1




      1





      @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

      – dasblinkenlight
      Aug 29 '12 at 21:37





      @KevinBallard Arguably, this is how the pre-increment vs. post-increment convention is using it. I think that using otherwise unused parameters for overloads is somewhat of a hack, though: overloads are resolved at compile time, so there is no reason not to use a distinct name rather than adding an unused parameter.

      – dasblinkenlight
      Aug 29 '12 at 21:37




      2




      2





      @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

      – Lily Ballard
      Aug 29 '12 at 21:41





      @dasblinkenlight: Good point about post-increment, but the type of the unnamed parameter can be used as well. This is actually (ab)used in STL for template parameters in various implementations. This sort of trick is mainly useful for template functions/classes, so you can change which function you're invoking based on traits of the template parameter types.

      – Lily Ballard
      Aug 29 '12 at 21:41




      7




      7





      Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

      – Roddy
      Aug 29 '12 at 22:39





      Worth mentioning that some compilers can warn about unused parameters: Making them unnamed will fix the warning.

      – Roddy
      Aug 29 '12 at 22:39













      10














      Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.



      This may happen for example for a method in a derived class, for a callback function or for a template parameter.



      Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.






      share|improve this answer




























        10














        Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.



        This may happen for example for a method in a derived class, for a callback function or for a template parameter.



        Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.






        share|improve this answer


























          10












          10








          10







          Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.



          This may happen for example for a method in a derived class, for a callback function or for a template parameter.



          Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.






          share|improve this answer













          Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.



          This may happen for example for a method in a derived class, for a callback function or for a template parameter.



          Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 29 '12 at 21:34









          65026502

          86.4k13114215




          86.4k13114215























              0














              Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".



              It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.



              It's used like this:



              class Friendly; // Just a forward declaration

              class Key {
              private:
              Key() {}
              friend class Friendly;
              };

              class Safe() {
              public:
              static int locked(Key, int i) {
              // Do something with `i`,
              // but the key is never used.
              return i;
              }
              private:
              static void inaccessible() {}
              };

              class Friendly {
              public:
              void foo() {
              int i = Safe::locked(Key(), 1); // OK
              int j = Safe::locked({}, 2); // OK, sice C++11
              }
              void bar() {
              Safe::inaccessible(); // Not OK, its inaccessible
              }
              };

              int i = Safe::locked(3); // Not OK, wrong parameters
              int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
              int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly





              share|improve this answer






























                0














                Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".



                It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.



                It's used like this:



                class Friendly; // Just a forward declaration

                class Key {
                private:
                Key() {}
                friend class Friendly;
                };

                class Safe() {
                public:
                static int locked(Key, int i) {
                // Do something with `i`,
                // but the key is never used.
                return i;
                }
                private:
                static void inaccessible() {}
                };

                class Friendly {
                public:
                void foo() {
                int i = Safe::locked(Key(), 1); // OK
                int j = Safe::locked({}, 2); // OK, sice C++11
                }
                void bar() {
                Safe::inaccessible(); // Not OK, its inaccessible
                }
                };

                int i = Safe::locked(3); // Not OK, wrong parameters
                int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
                int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly





                share|improve this answer




























                  0












                  0








                  0







                  Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".



                  It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.



                  It's used like this:



                  class Friendly; // Just a forward declaration

                  class Key {
                  private:
                  Key() {}
                  friend class Friendly;
                  };

                  class Safe() {
                  public:
                  static int locked(Key, int i) {
                  // Do something with `i`,
                  // but the key is never used.
                  return i;
                  }
                  private:
                  static void inaccessible() {}
                  };

                  class Friendly {
                  public:
                  void foo() {
                  int i = Safe::locked(Key(), 1); // OK
                  int j = Safe::locked({}, 2); // OK, sice C++11
                  }
                  void bar() {
                  Safe::inaccessible(); // Not OK, its inaccessible
                  }
                  };

                  int i = Safe::locked(3); // Not OK, wrong parameters
                  int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
                  int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly





                  share|improve this answer















                  Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".



                  It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.



                  It's used like this:



                  class Friendly; // Just a forward declaration

                  class Key {
                  private:
                  Key() {}
                  friend class Friendly;
                  };

                  class Safe() {
                  public:
                  static int locked(Key, int i) {
                  // Do something with `i`,
                  // but the key is never used.
                  return i;
                  }
                  private:
                  static void inaccessible() {}
                  };

                  class Friendly {
                  public:
                  void foo() {
                  int i = Safe::locked(Key(), 1); // OK
                  int j = Safe::locked({}, 2); // OK, sice C++11
                  }
                  void bar() {
                  Safe::inaccessible(); // Not OK, its inaccessible
                  }
                  };

                  int i = Safe::locked(3); // Not OK, wrong parameters
                  int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
                  int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Oct 9 '18 at 12:15

























                  answered Oct 9 '18 at 12:03









                  McSimMcSim

                  4291613




                  4291613























                      -2














                      I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.



                      // named-reference.cpp  
                      // Compile with: /EHsc
                      #include <iostream>
                      using namespace std;

                      // A class that contains a memory resource.
                      class MemoryBlock
                      {
                      // TODO: Add resources for the class here.
                      };

                      void g(const MemoryBlock&)
                      {
                      cout << "In g(const MemoryBlock&)." << endl;
                      }

                      void g(MemoryBlock&&)
                      {
                      cout << "In g(MemoryBlock&&)." << endl;
                      }

                      MemoryBlock&& f(MemoryBlock&& block)
                      {
                      g(block);
                      return block;
                      }

                      int main()
                      {
                      g(f(MemoryBlock()));
                      }


                      This example produces the following output:




                      In g(const MemoryBlock&).

                      In g(MemoryBlock&&).




                      In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).






                      share|improve this answer
























                      • This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

                        – Imad Nabil Alnatsheh
                        May 1 '17 at 22:41











                      • This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

                        – underscore_d
                        May 20 '17 at 12:06













                      • This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

                        – M.M
                        Oct 23 '18 at 2:31
















                      -2














                      I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.



                      // named-reference.cpp  
                      // Compile with: /EHsc
                      #include <iostream>
                      using namespace std;

                      // A class that contains a memory resource.
                      class MemoryBlock
                      {
                      // TODO: Add resources for the class here.
                      };

                      void g(const MemoryBlock&)
                      {
                      cout << "In g(const MemoryBlock&)." << endl;
                      }

                      void g(MemoryBlock&&)
                      {
                      cout << "In g(MemoryBlock&&)." << endl;
                      }

                      MemoryBlock&& f(MemoryBlock&& block)
                      {
                      g(block);
                      return block;
                      }

                      int main()
                      {
                      g(f(MemoryBlock()));
                      }


                      This example produces the following output:




                      In g(const MemoryBlock&).

                      In g(MemoryBlock&&).




                      In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).






                      share|improve this answer
























                      • This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

                        – Imad Nabil Alnatsheh
                        May 1 '17 at 22:41











                      • This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

                        – underscore_d
                        May 20 '17 at 12:06













                      • This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

                        – M.M
                        Oct 23 '18 at 2:31














                      -2












                      -2








                      -2







                      I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.



                      // named-reference.cpp  
                      // Compile with: /EHsc
                      #include <iostream>
                      using namespace std;

                      // A class that contains a memory resource.
                      class MemoryBlock
                      {
                      // TODO: Add resources for the class here.
                      };

                      void g(const MemoryBlock&)
                      {
                      cout << "In g(const MemoryBlock&)." << endl;
                      }

                      void g(MemoryBlock&&)
                      {
                      cout << "In g(MemoryBlock&&)." << endl;
                      }

                      MemoryBlock&& f(MemoryBlock&& block)
                      {
                      g(block);
                      return block;
                      }

                      int main()
                      {
                      g(f(MemoryBlock()));
                      }


                      This example produces the following output:




                      In g(const MemoryBlock&).

                      In g(MemoryBlock&&).




                      In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).






                      share|improve this answer













                      I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.



                      // named-reference.cpp  
                      // Compile with: /EHsc
                      #include <iostream>
                      using namespace std;

                      // A class that contains a memory resource.
                      class MemoryBlock
                      {
                      // TODO: Add resources for the class here.
                      };

                      void g(const MemoryBlock&)
                      {
                      cout << "In g(const MemoryBlock&)." << endl;
                      }

                      void g(MemoryBlock&&)
                      {
                      cout << "In g(MemoryBlock&&)." << endl;
                      }

                      MemoryBlock&& f(MemoryBlock&& block)
                      {
                      g(block);
                      return block;
                      }

                      int main()
                      {
                      g(f(MemoryBlock()));
                      }


                      This example produces the following output:




                      In g(const MemoryBlock&).

                      In g(MemoryBlock&&).




                      In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Feb 1 '17 at 20:53









                      Merry FitzpatrickMerry Fitzpatrick

                      51




                      51













                      • This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

                        – Imad Nabil Alnatsheh
                        May 1 '17 at 22:41











                      • This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

                        – underscore_d
                        May 20 '17 at 12:06













                      • This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

                        – M.M
                        Oct 23 '18 at 2:31



















                      • This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

                        – Imad Nabil Alnatsheh
                        May 1 '17 at 22:41











                      • This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

                        – underscore_d
                        May 20 '17 at 12:06













                      • This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

                        – M.M
                        Oct 23 '18 at 2:31

















                      This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

                      – Imad Nabil Alnatsheh
                      May 1 '17 at 22:41





                      This is logical, setting a name to a variable basically means "I'm gonna use it in the following statements", thus, lvalue. Specifying whether it's lvalue or rvalue doesn't depend on it's origin, but whether the reference in memory will persist after the statement.

                      – Imad Nabil Alnatsheh
                      May 1 '17 at 22:41













                      This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

                      – underscore_d
                      May 20 '17 at 12:06







                      This is unrelated. The question is about unnamed arguments, those lacking identifiers on the receiving function's side. You're talking about the value category passed from the caller's side - while incidentally including unnamed arguments, but not in a relevant way. Any difference here is because of the passed value category, not the presence or absence of a name for the argument. Because you don't forward/move the rvalue reference in the first, inner call to g(), the const& overload must win. The fact you need a name in order to forward it is completely incidental.

                      – underscore_d
                      May 20 '17 at 12:06















                      This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

                      – M.M
                      Oct 23 '18 at 2:31





                      This isn't even valid code (return block; should fail to compile). VTD, is irrelevant to the question.

                      – M.M
                      Oct 23 '18 at 2:31


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12186698%2fwhy-does-c-allow-unnamed-function-parameters%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      List item for chat from Array inside array React Native

                      Thiostrepton

                      Caerphilly