Last active
February 18, 2017 18:07
-
-
Save loliGothicK/196ac11095b48ca4b99ee0621306b70d to your computer and use it in GitHub Desktop.
C++の間違った知識に振り回されないために ref: http://qiita.com/_EnumHack/items/ced694a5629d1b2210b7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 変数がいっぱいある | |
int a{}, b{}, c{}; | |
double d{}, e{}, f{}; | |
std::string too_long_name_variable{}; | |
// ラムダ式 | |
auto result = [&a,&b,&c,&d,&e,&f,&too_long_name_variable](auto&& ...args){ | |
// ... | |
// 何らかの処理 | |
// ... | |
return result; // 計算結果結果を返す | |
}(1,2,3,4,5,5); // その場で呼び出す |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
やりたいこと | |
-> 可変長引数をバインドしておいて、後から指定した関数にわたす。 | |
※その際、可変長引数はムーブしてバインドしたいとする。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[args... = std::move(args)...](){} // 可変長引数をムーブキャプチャ! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int main() { | |
// バインドする変数 | |
hoge x{ 1 }; | |
std::cout << "#1 : " << x.get() << std::endl; | |
/* | |
ラムダ式バージョン | |
*/ | |
// #1 可変長引数をとる関数がラムダ式を返す | |
// #2 ラムダ式に可変長引数をバインドする | |
// #3 可変長引数を初期化キャプチャできないのでtupleに固めて初期化キャプチャ | |
// #4 ラムダ式が実行され、関数が指定されるとtupleを展開して関数に渡す | |
auto lambda = []( auto&&... args ) { | |
// #1 | |
return [/* #2,#3 */t = std::make_tuple( std::move( args )... )]( auto&& func, auto&& ... ){ | |
return cranberries::apply( func, t ); // #4 | |
}; | |
}(x); | |
// 呼び出し | |
lambda([]( auto&& head, auto&& ... ) { | |
std::cout << "#2 : " << head.get() << std::endl; | |
}); | |
// バインドする変数 | |
hoge y{ 2 }; | |
std::cout << "#3 : " << y.get() << std::endl; | |
/* | |
std::bindバージョン | |
*/ | |
// #1 可変長式数をとる関数がバインドオブジェクトを返す | |
// #2 bindに束縛させる関数はあとで指定する関数とその引数の両方を引数に取る関数(今回はラムダ式で書いた) | |
// #3 後で関数を指定するために第1引数はプレースホルダ | |
// #4 可変長引数をムーブしてバインドオブジェクトに束縛する | |
auto&& bind_expr = []( auto&& ...args ) { | |
// #1 | |
return std::bind( | |
/* #2 */[]( auto&& func, auto&& ...args ) { return func( std::forward<decltype(args)>( args )... ); }, | |
std::placeholders::_1, // #3 | |
std::move( args )... ); // #4 | |
}(y); | |
// 呼び出し | |
bind_expr( | |
[]( auto&& head, auto&& ... ) { | |
std::cout << "#4 : " << head.get() << std::endl; | |
}); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <functional> | |
#include <vector> | |
#include <initializer_list> | |
#include <utility> | |
#include <tuple> | |
#include <memory> | |
#include "time_elapsed.hpp" | |
namespace cranberries { | |
template < typename F, typename Tuple, size_t... I > | |
decltype(auto) apply_impl( F&& f, Tuple&& t, std::index_sequence<I...> ) { | |
return f( std::forward<decltype(std::get<I>( t ))>( std::get<I>( t ) )... ); | |
} | |
template < typename F, typename... Args > | |
decltype(auto) apply( F&& f, std::tuple<Args...> const& t ) { | |
return apply_impl( std::forward<F>( f ), t, std::index_sequence_for<Args...>{} ); | |
} | |
} | |
class hoge { | |
public: | |
hoge() = default; | |
~hoge() = default; | |
hoge( hoge const& x ) : ptr{ std::make_unique<int>( *x.ptr ) } { | |
std::cout << "copy constructed" << std::endl; | |
} | |
hoge( hoge&& x ) : ptr{ std::move( x.ptr ) } { | |
std::cout << "move constructed" << std::endl; | |
} | |
hoge( int a ) : ptr{ std::make_unique<int>( a ) } {} | |
hoge& operator=( hoge const& x ) { | |
std::cout << "copy assigned" << std::endl; | |
*ptr = *x.ptr; | |
return *this; | |
} | |
hoge& operator=( hoge&& x ) { | |
std::cout << "move assigned" << std::endl; | |
ptr = std::move( x.ptr ); | |
return *this; | |
} | |
auto* get() const { | |
return ptr.get(); | |
} | |
decltype(auto) print( std::ostream& os ) const { | |
return os << *ptr; | |
} | |
private: | |
std::unique_ptr<int> ptr{}; | |
}; | |
decltype(auto) operator<< ( std::ostream& os, hoge const& x ) { | |
return x.print( os ); | |
} | |
int main() { | |
hoge x{ 1 }; | |
std::cout << "#1 : " << x.get() << std::endl; | |
CRANBERRIES_TIME_ELAPSED_MICRO( | |
auto lambda = []( auto&&... args ) { | |
return[t = std::make_tuple( std::move( args )... )]( auto&& func, auto&& ... ){ | |
return cranberries::apply( func, t ); | |
}; | |
}(x); | |
lambda([]( auto&& head, auto&& ... ) { | |
std::cout << "#2 : " << head.get() << std::endl; | |
}); | |
); | |
hoge y{ 2 }; | |
std::cout << "#3 : " << y.get() << std::endl; | |
CRANBERRIES_TIME_ELAPSED_MICRO( | |
auto&& bind_expr = []( auto&& ...args ) { | |
return std::bind( | |
[]( auto&& func, auto&& ...args ) { return func( std::forward<decltype(args)>( args )... ); }, | |
std::placeholders::_1, | |
std::move( args )... ); | |
}(y); | |
bind_expr( | |
[]( auto&& head, auto&& ... ) { | |
std::cout << "#4 : " << head.get() << std::endl; | |
} ); | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#1 : 0000027810EEF2B0 | |
move constructed | |
move constructed | |
#2 : 0000027810EEF2B0 | |
1969[micro sec] | |
#3 : 0000027810EEF2D0 | |
move constructed | |
#4 : 0000027810EEF2D0 | |
1386[micro sec] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[t = std::make_tuple( std::move( args )... )] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#1 : 000002816499F3A0 | |
move constructed | |
#2 : 000002816499F3A0 | |
1437[micro sec] | |
#3 : 000002816499F4A0 | |
move constructed | |
#4 : 000002816499F4A0 | |
1444[micro sec] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment