Thread: "Decltype", class member access level, and temporary objects

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

    "Decltype", class member access level, and temporary objects

    Afternoon all,

    The class template shown below contains two std::vectors of different types. These are both held in an embedded std::tuple so that we can have a templatized at<I>(j) element accessor that calls std::vector::at(j) through std::get<I>. I like this a lot better than having separate column0(j) and column1(j) accessors.

    It works okay at first glance but fails if you try to convert the return value of at<I>(j) to a different type. Changing the access level of TwoVectors::TU to "public" does fix the problem, but that is really undesirable for this application.

    I'm using G++ 4.7.3, and have found a related bug in that version that *might* be the cause of this:

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52816

    However, I'm not sure whether the current problem is the same as the one addressed there, because it only seems to pop up where temporary objects are concerned.

    I don't know much about rvalue references yet, and std::get can return those... could my use of decltype() be the problem here?

    Anyways, here's the code.

    Thanks
    Grump

    Code:
    #include <vector>
    #include <tuple>
    
    
    // Template to hold two std::vectors of types T and U.
    // These are contained in an embedded 2-tuple.
    
    
    template <typename T, typename U>
    class TwoVectors
    {
      // The 2-tuple is private to ensure that both vectors are the same length.
    
    
      std::tuple< std::vector< T >, 
                  std::vector< U > > TU;
    
    
    public:
    
    
      // Resizer.
    
    
      void resize(int rows)
      {
        std::get<0>(TU).resize(rows);
        std::get<1>(TU).resize(rows);
      }
    
    
      // Element accessor.
      // This forwards to std::vector::at(i), via std::get<I>.
    
    
      template <int I>
      auto at(int i) -> decltype(std::get<I>(TU).at(i))
      {
        return std::get<I>(TU).at(i);
      }
    };
    
    
    int main()
    {
      // Construct a TwoVectors object and set some element values.
      // No problems with at<I>(i) occur here...
    
    
      TwoVectors<int, float> tv;
    
    
      tv.resize(2);
    
    
      tv.at<0>(0) = 2;
      tv.at<0>(1) = 4;
      tv.at<1>(0) = 3.;
      tv.at<1>(1) = 5.;
    
    
      // ... or here...
    
    
      float  x =        tv.at<1>(1);
    
    
      // ... but this implodes at compile time. 
    
    
      double y = double(tv.at<1>(1));
    
    
      /* The error message is:
    
    
      Type2.C:13:34: error: ‘std::tuple< std::vector<int, std::allocator<int> >, 
                                         std::vector<float, std::allocator<float> > 
                                       >
                                       TwoVectors<int, float>::TU’ is private
      Type2.C:55:32: error: within this context
    
    
      */
    }

  2. #2
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    You may have identified the correct bug.
    It works fine for me. (GCC 4.9.2)

    To bypass this, do not use decltype there and derive the return type using:
    http://en.cppreference.com/w/cpp/uti.../tuple_element
    Code:
      template <int I>
      typename std::tuple_element<I, std::tuple<T,U>>::type&  at(int i)
      {
        return std::get<I>(TU).at(i);
      }
    Last edited by manasij7479; 12-10-2014 at 11:45 PM.

  3. #3
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29
    Thanks for this Manasij. That has done the trick.

    You are probably right about this being the same bug that was cited in my earlier post.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-08-2014, 08:12 PM
  2. Getting "undeclared member" error with derived class
    By indigo0086 in forum C++ Programming
    Replies: 4
    Last Post: 10-07-2007, 06:41 AM
  3. Getting a:"member is not of class type" error
    By indigo0086 in forum C++ Programming
    Replies: 10
    Last Post: 11-20-2006, 10:19 AM
  4. "ambiguous access to class/struct/union member"
    By Mr_Jack in forum C++ Programming
    Replies: 1
    Last Post: 12-16-2003, 12:15 PM
  5. how to access "private or protected " in Class
    By johnnypiere in forum C++ Programming
    Replies: 3
    Last Post: 12-17-2002, 02:33 AM