True_typedef in class constructors

Help
mccory
2009-06-16
2013-04-26
  • mccory
    mccory
    2009-06-16

    I'm trying to use the stlsoft::true_typedef in a class constructor.  I can define a unique variable and use it in my class constructor.  I can initialize the constructor with the true_typedef variable directly in the constructor as long as everything is created in the constructor.  I can't initialize the constructor with a true_typedef that has an existing variable (of the underline type) passed to it.  The code below shows the problem I'm running into.

    STLSOFT_GEN_OPAQUE(path_type);
    typedef stlsoft::true_typedef<std::string, path_type>  Pathname;

    class Rdi {
    private:
      Rdi(void);
    public:
      Rdi(Pathname const& pathname)
      : m_Pathname(pathname)
      {}

    private:
      Pathname  m_Pathname;
    };

    Rdi  works(Pathname(“C:\\path”));

    std::string const path = “C:\\path”;
    Rdi  doesnotwork(Pathname(path));  //Get an error about an incorrect function prototype.

    //Workaround
    //std::string const path = “C:\\path”;
    //Pathname const pathTemp(path);
    //Rdi  doesnotwork(pathTemp);

     
    • Matt Wilson
      Matt Wilson
      2009-06-16

      Hi

      I was originally going to answer as follow below. Then I compiled yours with a few more compilers, and realised you're hitting one of C++'s dark little corners. The line in question is being (correctly) interpreted by the compiler as a function declaration, rather than a construction. Scott Meyers christened this "C++'s most vexing parse", in Effective STL, IIRC

      HTH

      Matt

      [Original answer follows]

      What compiler are you using?

      I've just compiled the following program with VC++ 6 and 9 (with maximum warnings) and it goes fine.

      /* /////////////////////////////////////////////////////////////////////////
      * File:        example.stlsoft.util.true_typedef.cpp
      *
      * Purpose:     Implementation file for the example.stlsoft.util.true_typedef project.
      *
      * Created:     17th June 2009
      * Updated:     17th June 2009
      *
      * Status:      Wizard-generated
      *
      * License:     (Licensed under the Synesis Software Open License)
      *
      *              Copyright (c) 2009, Synesis Software Pty Ltd.
      *              All rights reserved.
      *
      *              www:        http://www.synesis.com.au/software
      *
      * ////////////////////////////////////////////////////////////////////// */

      /* STLSoft Header Files */
      #include <stlsoft/util/true_typedef.hpp>

      /* Standard C++ Header Files */
      #include <exception>
      #include <string>

      /* Standard C Header Files */
      #include <stdio.h>
      #include <stdlib.h>

      /* /////////////////////////////////////////////////////////////////////////
      * Typedefs
      */

      class File
      {
          STLSOFT_GEN_OPAQUE(pathname_u_);
      public:
          typedef stlsoft::true_typedef<std::string, pathname_u_>     pathname_type;

      public:
          File(pathname_type const& pathname)
              : m_pathname(pathname.base_type_value())
      //      : m_pathname(pathname)
          {}

      private:
          std::string     m_pathname;
      //  pathname_type   m_pathname;
      };

      /* /////////////////////////////////////////////////////////////////////////
      * Forward declarations
      */

      /* ////////////////////////////////////////////////////////////////////// */

      static int main_(int /* argc */, char** /*argv*/)
      {
          File::pathname_type path("C:\\temp");

          File                file1(path);

      //  File                file2("C:\\temp");                // Does not compile: correct!

      //  File                file3(std::string("C:\\temp"));    // Does not compile: correct!

          File                file4(File::pathname_type("C:\\temp"));

          return EXIT_SUCCESS;
      }

      int main(int argc, char** argv)
      {
          try
          {
              return main_(argc, argv);
          }
          catch(std::exception& x)
          {
              fprintf(stderr, "Unhandled error: %s\n", x.what());
          }
          catch(...)
          {
              fprintf(stderr, "Unhandled unknown error\n");
          }

          return EXIT_FAILURE;
      }

      /* ////////////////////////////////////////////////////////////////////// */

       
    • mccory
      mccory
      2009-06-18

      Thanks for the help.  I've never heard of that problem before.