From: khizmax Date: Thu, 5 Mar 2015 20:59:04 +0000 (+0300) Subject: Fixe passing an argument pack to a lambda X-Git-Tag: v2.1.0~305^2~20 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=83a43db3a8d19308b8d5fde831fa1a3e96611887;p=libcds.git Fixe passing an argument pack to a lambda --- diff --git a/cds/container/bronson_avltree_map_rcu.h b/cds/container/bronson_avltree_map_rcu.h index f36f53d2..25c7e5d9 100644 --- a/cds/container/bronson_avltree_map_rcu.h +++ b/cds/container/bronson_avltree_map_rcu.h @@ -236,27 +236,37 @@ namespace cds { namespace container { template bool emplace( K&& key, Args&&... args ) { -# if CDS_COMPILER != CDS_COMPILER_MSVC - auto helper = []( typename std::decay::type&&... args ) -> mapped_type * - { - return cxx_allocator().New( std::move(args)...); - }; -# endif - + // gcc/clang error: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 + // see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#904 - this is what we need + // Probably, the following code is not so efficient, since we pass lvalues instead rvalues to lambda + //TODO: study how to pass a parameter pack to a lambda efficiently using perfect forwarding return base_class::do_update( key, key_comparator(), - [&]( node_type * pNode ) -> mapped_type * + [&args...]( node_type * pNode ) -> mapped_type * { assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr ); CDS_UNUSED( pNode ); -# if CDS_COMPILER == CDS_COMPILER_MSVC return cxx_allocator().New( std::forward(args)...); -# else - // gcc/clang error: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 - return helper( args... ); -# endif }, update_flags::allow_insert ) == update_flags::result_inserted; +# if 0 + // another implementation (from http://stackoverflow.com/questions/14191989/how-do-i-use-variadic-perfect-forwarding-into-a-lambda) + // Does not work on vc12 + auto lambda = []( Args&&... args) -> mapped_type* { return cxx_allocator().New( std::forward(args)...); }; + auto helper = std::bind( + lambda, + std::forward(args)... + ); + return base_class::do_update( key, key_comparator(), + [&helper]( node_type * pNode ) -> mapped_type * + { + assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr ); + CDS_UNUSED( pNode ); + return helper(); + }, + update_flags::allow_insert + ) == update_flags::result_inserted; +# endif } /// Ensures that the \p key exists in the map