要将一系列函数(不同类型)及其标识存储在同一个容器中,然后通过它们的标识调用它们,我首先将一个通用lambda实现为“list”容器,然后打包标识和函数体在std :: pair中,将对存储在'list'中;
'list'的代码是
template< typename ... Args >
auto list( Args ... args )
{
return [=]( auto func ){ return func( args... ); };
}
然后以这种方式定义'cons',插入新对
template< typename List_1, typename List_2 >
auto cons( List_1 list_1, List_2 list_2 )
{
return list_1( [=]( auto ... args_1 ){ return list_2( [=]( auto ... args_2 ){ return list( args_2..., args_1...); } ); } );
}
但不幸的是,似乎这个“缺点”生成的“列表”无法正确保持对,请参阅此处的完整代码:
http://melpon.org/wandbox/permlink/fo9tQnObFM4cyNcV
然后我将'cons'改为
template< typename List_1, typename List_2 >
auto cons( List_1 list_1, List_2 list_2 )
{
auto layer_1 = [=]( auto ... args_1 ) { return list_2( [=]( auto ... args_2 ) { return list( args_1..., args_2... ); } ); };
return list_1( layer_1 );
}
然后它可以工作,请看这里:
http://melpon.org/wandbox/permlink/GpXEkkfztdOxapIL
但这两个'缺点'的实现与我相同,有人可以解释一下这个问题吗?
编辑:
根据Yakk的建议,我纠正了错字并将代码修改为
template< typename ... Args >
auto list( Args ... args )
{
return [=]( auto func ){ return func( args... ); };
}
#ifdef V1
template< typename List_1, typename List_2 >
auto cons( List_1 list_1, List_2 list_2 )
{
auto layer_1 = [=]( auto ... args_1 ) { return list_2( [=]( auto ... args_2 ) { return list( args_1..., args_2... ); } ); };
return list_1( layer_1 );
}
#endif
#ifdef V2
template< typename List_1, typename List_2 >
auto cons( List_1 list_1, List_2 list_2 )
{
return list_1( [=]( auto ... args_1 ){ return list_2( [=]( auto ... args_2 ){ return list( args_1..., args_2...); } ); } );
}
#endif
template< typename Func, typename List >
auto map( Func func, List the_list )
{
return the_list( [=]( auto ... elems ){ return list( func(elems)... ); } );
}
#include <string>
#include <utility>
#include <type_traits>
#include <iostream>
int main()
{
auto mfl = cons( cons( list( std::make_pair( std::string{"f1"}, [](int i){ return i; } ) ),
list( std::make_pair( std::string{"f2"}, []( double x, double y){ return x*y; } ) ) ),
list( std::make_pair( std::string{"f3"}, [](std::string s){ return s+s; } ) ) );
auto pair_printer = []( auto the_pair ) { std::cout << "id:" << the_pair.first << "\n"; return the_pair; };
map( pair_printer, mfl );
return 0;
}
然后在clang ++ v3.5和g ++ 4.9.2
上测试了上面的代码使用clang ++ v3.5和第一个'cons'(V1)
clang++ -o tmp tmp.cc -std=c++1y -lc++ -lc++abi -DV1
输出正确:
id:f1
id:f2
id:f3
第二个'缺点'(V2)
clang++ -o tmp tmp.cc -std=c++1y -lc++ -lc++abi -DV2
输出很乱:
id:f1
id: 4S� 4S�
id:4S��4S��4S��S���
�S��
84S��4S�
使用g ++ 4.9.2,两个版本都给出了预期的输出。
这是clang ++的错误吗?
多年后更新:这个奇怪的行为已在最新版本(clang 6.0.1)中得到纠正。