Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7061141
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T04:26:16+00:00 2026-05-28T04:26:16+00:00

I need a generic function that can take either a const or non-const reference

  • 0

I need a generic function that can take either a const or non-const reference to a container, and return the corresponding reference to elements qualified as per the container.

Something along these lines:

template <typename C>
auto get_nth( C& c, int i ) -> /* not-sure-what, but let's call it T */
{
      //.... some tricky code here ...
}

I would like to stress that if C expands to

SomeContainer const

then T would be

SomeContainer::const_reference

and otherwise

SomeContainer::reference

I think I can put it together using type traits and mtl if, my question is if there is a shorter, cleaner way.

I’m using C++x11 (obviously) and boost.

Thanks in advance.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T04:26:17+00:00Added an answer on May 28, 2026 at 4:26 am

    I think you are looking for typename C::reference, see 23.2.1 [container.requirements.general] §4.


    Oh wait, the above doesn’t work if C is already const. But wait, decltype to the rescue!

    template <typename C>
    auto get_nth( C&& c, int i ) -> decltype(*c.begin())
    {
          //.... some tricky code here ...
    }
    

    If you also want to support C-style arrays which have no begin member function:

    #include <iterator>
    
    template <typename C>
    auto get_nth( C&& c, int i ) -> decltype(*std::begin(c))
    {
          //.... some tricky code here ...
    }
    

    And the implementation really isn’t that tricky:

    #include <iterator>
    
    template <typename C>
    auto get_nth( C&& c, int i ) -> decltype(*std::begin(c))
    {
        auto it = std::begin(c);
        std::advance(it, i);
        return *it;
    }
    

    Note that the above solution accepts lvalues and rvalues, but it will always return an lvalue reference. Depending on the client code, this may be a performance concern. Take the following example code:

    std::string s = get_nth(std::vector<std::string> { "hello", "world" }, 0);
    

    This will copy the result into s, even though moving it would be perfectly valid (and, of course, faster).

    To solve this problem, we need two overloads, one for lvalues and one for rvalues:

    #include <iterator>
    #include <type_traits>
    
    template <typename C>
    auto get_nth( C& c, int i ) -> decltype(*std::begin(c))
    {
        auto it = std::begin(c);
        std::advance(it, i);
        return *it;
    }
    
    template <typename C>
    auto get_nth( C&& c, int i )
    -> typename std::enable_if<std::is_rvalue_reference<C&&>::value,
                               decltype(std::move(*std::begin(c)))>::type
    {
        auto it = std::begin(c);
        std::advance(it, i);
        return std::move(*it);
    }
    

    Now the result will be moved into s. The enable_if part is necessary because due to reference collapsing rules, C&& can also bind to lvalues, and then the call to initialize s would be ambiguous.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need a generic container that keeps its elements sorted and can be asked
I want to create generic function that will need only parameter as Stored procedure
I need to write a generic procedure that set value for one column or
I need a Generic function to retrieve the name or value of an enum
I need to have a collection of generic functions, but I can't get it
I have a generic function that returns URLs. (It's a plugin function that returns
I am trying to create a function that accepts a generic List<T> and iterates
I would like some feedback on how we can best write a generic function
I have a generic class called Repository. This class has a function that calls
While writing several math utilities I bumped into need to implement generic utility that

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.