Thread: Embedded std::function initialization question

  1. #1
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29

    Embedded std::function initialization question

    Here is another one that I can't easily figure out.

    The attached code works. However, if you replace the definition of embed_wrap_this2 in class MainClass with the commented-out line marked HERE (line 78), overload resolution problems result.

    Anyone know why braced initialization works here but copy initialization doesn't? This bugs me -- 'has me thinking that there could be something wrong here that I'm not seeing.

    I'm using GCC 4.7.3, by the way. Here's the code:

    Code:
    #include <functional>
    
    
    // A function template that takes an std::function and its arguments as 
    //   parameters. We'll make it simple, but, in reality, it would use "func" to 
    //   do something complicated with the contents of "one" and "two".
    
    
    template< class One, 
              class Two, 
              class... More
            >
    int wrapper(std::function<int(One const&, Two const&, More...)> const& func,
                One const& one,
                Two const& two,
                More...    more)
    {
      return 2*func(one, two, more...);
    }
    
    
    // A couple of function templates, to be used in place of "func" above.
    // The first two arguments must have public int value() functions.
    
    
    template<class One, class Two>
    int
    wrap_this2(One const& one, Two const& two)
    {
      return one.value() + two.value();
    }
    
    
    template<class One, class Two, class Three>
    int
    wrap_this3(One const& one, Two const& two, Three three)
    {
      return one.value() + two.value() + three;
    }
    
    
    // Two PODS classes, with public int value() functions, to be used as
    //   arguments of the above function templates
    
    
    class PODS1
    { 
      int i;
      public: PODS1(int _i) : i(_i) { };
              int value() const { return i; }
    };
    
    
    class PODS2
    { 
      int i;
      public: PODS2(int _i) : i(_i) { };
              int value() const { return i; }
    };
    
    
    // Main class.
    
    
    class MainClass
    {
      int i;
    
    
      // Embedded std::functions that wrap two specializations of wrap_this2/3
      //   in a form that can go straight to the argument list of "wrapper".
    
    
      std::function<int(PODS1 const&, 
                        PODS2 const&)
                   > 
                   embed_wrap_this2 { wrap_this2<PODS1, PODS2> } ;
                 //embed_wrap_this2 = wrap_this2<PODS1, PODS2>   ;  // HERE
    
    
      std::function<int(PODS1 const&, 
                        PODS2 const&, 
                        int)
                   > 
                   embed_wrap_this3 { wrap_this3<PODS1, PODS2, int> } ;
    
    
     public:
      int member_func(int choose)
      {
        PODS1 first(1);
        PODS2 second(2);
        int   third = 3;
    
    
        // Case 4 is the same as case 2 but without the embedded function
    
    
        switch(choose)
        {
          case 2:
            return wrapper<PODS1, PODS2>(embed_wrap_this2, first, second);
          case 3:
            return wrapper<PODS1, PODS2, int>
                                        (embed_wrap_this3, first, second, third);
          case 4:
            return wrapper<PODS1, PODS2>
                          (std::function<int(PODS1 const&, PODS2 const&)>
                                        (wrap_this2<PODS1, PODS2>), 
                                        first, second);
          default:
            return 0;
        }
      }
    };
    
    
    #include <cstdio>
    
    
    int main()
    {
      MainClass obj;
    
    
      printf("%d %d %d\n", obj.member_func(2), 
                           obj.member_func(3), 
                           obj.member_func(4));
    }
    Last edited by Grumpulus; 03-02-2015 at 09:01 PM. Reason: Entering line number of "HERE"

  2. #2
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    The builds fine in clang with:
    Code:
    embed_wrap_this2 = wrap_this2<PODS1, PODS2> ;
    Probably a compiler bug in GCC.
    If you do not find a better explanation, please report it.

  3. #3
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29
    Thanks for looking into this Manasij. That kind of unexplained behaviour often is a harbinger of deeper problems, so your result sets my mind at (relative) ease.

    Can someone please try running this on a version of GCC more recent than 4.7.3 before any bug reports get filed? There's a good chance this has been fixed already.

    I'd do it myself, but I can't use GCC 4.8+. (I'll refrain from explaining why to avoid ranting.)

  4. #4
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Grumpulus View Post
    Thanks for looking into this Manasij. That kind of unexplained behaviour often is a harbinger of deeper problems, so your result sets my mind at (relative) ease.

    Can someone please try running this on a version of GCC more recent than 4.7.3 before any bug reports get filed? There's a good chance this has been fixed already.

    I'd do it myself, but I can't use GCC 4.8+. (I'll refrain from explaining why to avoid ranting.)
    It does not build with GCC 4.9.2 (options -stc=c++14 , 11 both).

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    It does not build with GCC 4.9.2 (options -stc=c++14 , 11 both).
    O_o

    You should update your build.

    The code works fine on my build of "GCC" and "Arch" 4.9.2-3 version package.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  6. #6
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Have you uncommented the 'bad' part ?
    Code:
                   embed_wrap_this2 { wrap_this2<PODS1, PODS2> } ;
                 //embed_wrap_this2 = wrap_this2<PODS1, PODS2>   ;  // HERE

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Have you uncommented the 'bad' part ?
    >_<

    Yes.

    I also tested again when I read your post and found my mistake.

    I copied my build--a later package version--to my network repository ("Arch") at the same time I copied other updates of custom packages so I could upgrade my other machines.

    A "pacman -Syu" installed my custom build over the normal "GCC 4.9.2-3" installation.

    (I would normally use a 'chroot" environment for bleeding updates.)

    My build has dozens of list patches not yet in mains as far as I know.

    I'm sorry for the confusion.

    *shrug*

    And now I have to go rollback several machines...

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. initialization of function pointer
    By tilman in forum C Programming
    Replies: 8
    Last Post: 04-28-2013, 11:29 AM
  2. Ask two question about embedded assembler
    By leetow2003 in forum Linux Programming
    Replies: 3
    Last Post: 07-30-2011, 08:55 PM
  3. Help uderstanding a function with embedded SQL
    By cjohnman in forum C Programming
    Replies: 0
    Last Post: 04-29-2008, 01:13 PM
  4. Question on embedded systems
    By ssharish2005 in forum C Programming
    Replies: 3
    Last Post: 08-12-2007, 02:28 PM
  5. Embedded Tools question...
    By ober in forum Windows Programming
    Replies: 1
    Last Post: 09-28-2001, 02:30 PM

Tags for this Thread