How to overload an in-place and a copying string manipulation functions?












0















I would like to be able to do the following:



std::cout << str_manip("string to manipulate");


as well as



std::string str;
str_manip(str);
std::cout << str;


For this, I have two functions



#include <string>

// copying
std::string str_manip(std::string str)
{
// manipulate str
return str;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}


but they produce the following error:



error: call of overloaded 'str_manip(std::__cxx11::string&)' is ambiguous


How can I overcome this?










share|improve this question


















  • 1





    What about std::cout << str_manip(str)? Is that supposed to use the in-place of version of the copying version?

    – François Andrieux
    Nov 13 '18 at 19:08








  • 1





    Can I just say that having two functions with the same names where one of them modifies the input and the other doesn't... that's wildly dangerous. Someone is guaranteed to get it wrong and make a bug in the code. Please don't do that.

    – Mooing Duck
    Nov 13 '18 at 19:20


















0















I would like to be able to do the following:



std::cout << str_manip("string to manipulate");


as well as



std::string str;
str_manip(str);
std::cout << str;


For this, I have two functions



#include <string>

// copying
std::string str_manip(std::string str)
{
// manipulate str
return str;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}


but they produce the following error:



error: call of overloaded 'str_manip(std::__cxx11::string&)' is ambiguous


How can I overcome this?










share|improve this question


















  • 1





    What about std::cout << str_manip(str)? Is that supposed to use the in-place of version of the copying version?

    – François Andrieux
    Nov 13 '18 at 19:08








  • 1





    Can I just say that having two functions with the same names where one of them modifies the input and the other doesn't... that's wildly dangerous. Someone is guaranteed to get it wrong and make a bug in the code. Please don't do that.

    – Mooing Duck
    Nov 13 '18 at 19:20
















0












0








0








I would like to be able to do the following:



std::cout << str_manip("string to manipulate");


as well as



std::string str;
str_manip(str);
std::cout << str;


For this, I have two functions



#include <string>

// copying
std::string str_manip(std::string str)
{
// manipulate str
return str;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}


but they produce the following error:



error: call of overloaded 'str_manip(std::__cxx11::string&)' is ambiguous


How can I overcome this?










share|improve this question














I would like to be able to do the following:



std::cout << str_manip("string to manipulate");


as well as



std::string str;
str_manip(str);
std::cout << str;


For this, I have two functions



#include <string>

// copying
std::string str_manip(std::string str)
{
// manipulate str
return str;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}


but they produce the following error:



error: call of overloaded 'str_manip(std::__cxx11::string&)' is ambiguous


How can I overcome this?







c++ function-overloading ambiguous-call






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 18:58









SparklerSparkler

780824




780824








  • 1





    What about std::cout << str_manip(str)? Is that supposed to use the in-place of version of the copying version?

    – François Andrieux
    Nov 13 '18 at 19:08








  • 1





    Can I just say that having two functions with the same names where one of them modifies the input and the other doesn't... that's wildly dangerous. Someone is guaranteed to get it wrong and make a bug in the code. Please don't do that.

    – Mooing Duck
    Nov 13 '18 at 19:20
















  • 1





    What about std::cout << str_manip(str)? Is that supposed to use the in-place of version of the copying version?

    – François Andrieux
    Nov 13 '18 at 19:08








  • 1





    Can I just say that having two functions with the same names where one of them modifies the input and the other doesn't... that's wildly dangerous. Someone is guaranteed to get it wrong and make a bug in the code. Please don't do that.

    – Mooing Duck
    Nov 13 '18 at 19:20










1




1





What about std::cout << str_manip(str)? Is that supposed to use the in-place of version of the copying version?

– François Andrieux
Nov 13 '18 at 19:08







What about std::cout << str_manip(str)? Is that supposed to use the in-place of version of the copying version?

– François Andrieux
Nov 13 '18 at 19:08






1




1





Can I just say that having two functions with the same names where one of them modifies the input and the other doesn't... that's wildly dangerous. Someone is guaranteed to get it wrong and make a bug in the code. Please don't do that.

– Mooing Duck
Nov 13 '18 at 19:20







Can I just say that having two functions with the same names where one of them modifies the input and the other doesn't... that's wildly dangerous. Someone is guaranteed to get it wrong and make a bug in the code. Please don't do that.

– Mooing Duck
Nov 13 '18 at 19:20














2 Answers
2






active

oldest

votes


















1














The problem is with this call:



std::string str;
str_manip(str);
std::cout << str;


The compiler doesn't know which version of str_manip to call.



You can change your functions to look like this:



#include <string>

// copying
std::string str_manip(const std::string& str)
{
std::string dup = str;
// manipulate dup
return dup;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}


Now, the compiler knows that the ambiguous call has to be the function that takes the non-const parameter. You can also be sure that your call that returns a std::string to the << operator isn't modifying your string.






share|improve this answer































    1














    This might be not the thing you are looking for, but for your code



    std::cout << str_manip("string to manipulate");


    the parameter to str_manip is not a string but const char* (actually an array, but convertible to a char pointer). You can overload based on that.



    std::string str_manip(const char* s)
    {
    std::string str(s); // create str
    // manipulate str
    return str;
    }




    However, let's look at the big picture. When you see str_manip in your code, does this mean "change the string" or "make a new string based on the given string"? Do you want to be intentionally ambivalent on the real meaning?



    Consider yourself reading your code in 1 year in future. What will you think when you see a call to str_manip - does this mutate its parameter? Does the answer to the previous question depend on context?



    The goal in writing code is to make it clear, especially in a multi-paradigm language like C++. So, in my opinion, just don't do overloading that you are thinking about. Instead, make 2 distinct names, like



    void frobnicate_str(std::string&) {...}
    std::string get_frobnicated_str(std::string) {...}





    share|improve this answer

























      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%2f53287805%2fhow-to-overload-an-in-place-and-a-copying-string-manipulation-functions%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      The problem is with this call:



      std::string str;
      str_manip(str);
      std::cout << str;


      The compiler doesn't know which version of str_manip to call.



      You can change your functions to look like this:



      #include <string>

      // copying
      std::string str_manip(const std::string& str)
      {
      std::string dup = str;
      // manipulate dup
      return dup;
      }

      // in-place
      void str_manip(std::string& str)
      {
      // manipulate str
      }


      Now, the compiler knows that the ambiguous call has to be the function that takes the non-const parameter. You can also be sure that your call that returns a std::string to the << operator isn't modifying your string.






      share|improve this answer




























        1














        The problem is with this call:



        std::string str;
        str_manip(str);
        std::cout << str;


        The compiler doesn't know which version of str_manip to call.



        You can change your functions to look like this:



        #include <string>

        // copying
        std::string str_manip(const std::string& str)
        {
        std::string dup = str;
        // manipulate dup
        return dup;
        }

        // in-place
        void str_manip(std::string& str)
        {
        // manipulate str
        }


        Now, the compiler knows that the ambiguous call has to be the function that takes the non-const parameter. You can also be sure that your call that returns a std::string to the << operator isn't modifying your string.






        share|improve this answer


























          1












          1








          1







          The problem is with this call:



          std::string str;
          str_manip(str);
          std::cout << str;


          The compiler doesn't know which version of str_manip to call.



          You can change your functions to look like this:



          #include <string>

          // copying
          std::string str_manip(const std::string& str)
          {
          std::string dup = str;
          // manipulate dup
          return dup;
          }

          // in-place
          void str_manip(std::string& str)
          {
          // manipulate str
          }


          Now, the compiler knows that the ambiguous call has to be the function that takes the non-const parameter. You can also be sure that your call that returns a std::string to the << operator isn't modifying your string.






          share|improve this answer













          The problem is with this call:



          std::string str;
          str_manip(str);
          std::cout << str;


          The compiler doesn't know which version of str_manip to call.



          You can change your functions to look like this:



          #include <string>

          // copying
          std::string str_manip(const std::string& str)
          {
          std::string dup = str;
          // manipulate dup
          return dup;
          }

          // in-place
          void str_manip(std::string& str)
          {
          // manipulate str
          }


          Now, the compiler knows that the ambiguous call has to be the function that takes the non-const parameter. You can also be sure that your call that returns a std::string to the << operator isn't modifying your string.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 19:10









          contrapantscontrapants

          600214




          600214

























              1














              This might be not the thing you are looking for, but for your code



              std::cout << str_manip("string to manipulate");


              the parameter to str_manip is not a string but const char* (actually an array, but convertible to a char pointer). You can overload based on that.



              std::string str_manip(const char* s)
              {
              std::string str(s); // create str
              // manipulate str
              return str;
              }




              However, let's look at the big picture. When you see str_manip in your code, does this mean "change the string" or "make a new string based on the given string"? Do you want to be intentionally ambivalent on the real meaning?



              Consider yourself reading your code in 1 year in future. What will you think when you see a call to str_manip - does this mutate its parameter? Does the answer to the previous question depend on context?



              The goal in writing code is to make it clear, especially in a multi-paradigm language like C++. So, in my opinion, just don't do overloading that you are thinking about. Instead, make 2 distinct names, like



              void frobnicate_str(std::string&) {...}
              std::string get_frobnicated_str(std::string) {...}





              share|improve this answer






























                1














                This might be not the thing you are looking for, but for your code



                std::cout << str_manip("string to manipulate");


                the parameter to str_manip is not a string but const char* (actually an array, but convertible to a char pointer). You can overload based on that.



                std::string str_manip(const char* s)
                {
                std::string str(s); // create str
                // manipulate str
                return str;
                }




                However, let's look at the big picture. When you see str_manip in your code, does this mean "change the string" or "make a new string based on the given string"? Do you want to be intentionally ambivalent on the real meaning?



                Consider yourself reading your code in 1 year in future. What will you think when you see a call to str_manip - does this mutate its parameter? Does the answer to the previous question depend on context?



                The goal in writing code is to make it clear, especially in a multi-paradigm language like C++. So, in my opinion, just don't do overloading that you are thinking about. Instead, make 2 distinct names, like



                void frobnicate_str(std::string&) {...}
                std::string get_frobnicated_str(std::string) {...}





                share|improve this answer




























                  1












                  1








                  1







                  This might be not the thing you are looking for, but for your code



                  std::cout << str_manip("string to manipulate");


                  the parameter to str_manip is not a string but const char* (actually an array, but convertible to a char pointer). You can overload based on that.



                  std::string str_manip(const char* s)
                  {
                  std::string str(s); // create str
                  // manipulate str
                  return str;
                  }




                  However, let's look at the big picture. When you see str_manip in your code, does this mean "change the string" or "make a new string based on the given string"? Do you want to be intentionally ambivalent on the real meaning?



                  Consider yourself reading your code in 1 year in future. What will you think when you see a call to str_manip - does this mutate its parameter? Does the answer to the previous question depend on context?



                  The goal in writing code is to make it clear, especially in a multi-paradigm language like C++. So, in my opinion, just don't do overloading that you are thinking about. Instead, make 2 distinct names, like



                  void frobnicate_str(std::string&) {...}
                  std::string get_frobnicated_str(std::string) {...}





                  share|improve this answer















                  This might be not the thing you are looking for, but for your code



                  std::cout << str_manip("string to manipulate");


                  the parameter to str_manip is not a string but const char* (actually an array, but convertible to a char pointer). You can overload based on that.



                  std::string str_manip(const char* s)
                  {
                  std::string str(s); // create str
                  // manipulate str
                  return str;
                  }




                  However, let's look at the big picture. When you see str_manip in your code, does this mean "change the string" or "make a new string based on the given string"? Do you want to be intentionally ambivalent on the real meaning?



                  Consider yourself reading your code in 1 year in future. What will you think when you see a call to str_manip - does this mutate its parameter? Does the answer to the previous question depend on context?



                  The goal in writing code is to make it clear, especially in a multi-paradigm language like C++. So, in my opinion, just don't do overloading that you are thinking about. Instead, make 2 distinct names, like



                  void frobnicate_str(std::string&) {...}
                  std::string get_frobnicated_str(std::string) {...}






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 13 '18 at 19:22

























                  answered Nov 13 '18 at 19:13









                  anatolyganatolyg

                  16.9k44590




                  16.9k44590






























                      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%2f53287805%2fhow-to-overload-an-in-place-and-a-copying-string-manipulation-functions%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

                      Xamarin.iOS Cant Deploy on Iphone

                      Glorious Revolution

                      Dulmage-Mendelsohn matrix decomposition in Python