c++ - Is there a way to emplace return value? -


// version 1 struct range { int begin, end; }; inline range getrange() {     int newbegin, newend;     // calculations     return {newbegin, newend}; } struct test {     std::vector<range> ranges;     inline void intensive()     {         ranges.push_back(getrange());         // or ranges.emplace_back(getrange());         // (gives same performance results)     } }; 

// version 2 struct range { int begin, end; }; struct test {     std::vector<range> ranges;     inline void intensive()     {        int newbegin, newend;        // calculations        ranges.emplace_back(newbegin, newend);     } }; 

version 2 faster version 1.

fact is, getrange() used multiple classes. if apply version 2, there lot of code duplication.

also, cannot pass ranges non-const reference getrange(), other classes use std::stack instead of std::vector. have create multiple overloads , have more code duplications.

is there common way/idiom emplace return value?

following our discussion in comments using sfinae allow emplacement on type of container (whether supports emplace or emplace_back), here example implementation.

you need way detect whether emplace or emplace_back available, , dispatch call accordingly. purpose, we'll use sfinae:

namespace detail {     template<typename t, typename... args>     auto emplace_impl(int, t& c, args&&... pp)         -> decltype(c.emplace_back(std::forward<args>(pp)...))     {         return c.emplace_back(std::forward<args>(pp)...);     }      template<typename t, typename... args>     auto emplace_impl(long, t& c, args&&... pp)         -> decltype(c.emplace(std::forward<args>(pp)...))     {         return c.emplace(std::forward<args>(pp)...);     } } // namespace detail  template<typename t, typename... args> auto emplace(t& c, args&&... pp)     -> decltype(detail::emplace_impl(0, c, std::forward<args>(pp)...)) {     return detail::emplace_impl(0, c, std::forward<args>(pp)...); } 

kudos @dyp provided much nicer , shorter c++11 solution (see comments). previous traits-based solutions (revisions 3 & 4) lot more verbose.


using quite straightforward:

template<typename container> void test_emplace() {   container c;   emplace(c, 3); }  int main() {   test_emplace<std::queue<int>>();   test_emplace<std::stack<int>>();   test_emplace<std::deque<int>>();   test_emplace<std::list<int>>();   test_emplace<std::vector<int>>(); } 

i'll let bridge gap between test_emplace() usage example , actual code, shouldn't hard now. ;)


Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -