我的助推凤凰懒惰功能有什么问题?
What's wrong with my boost phoenix lazy function?
我有以下代码(在MSVC9上使用boost 1.55(:
struct pair_first_impl
{
template<class TPair> struct result { typedef typename TPair::first_type type; };
template<class TPair>
typename TPair::first_type const& operator() (TPair const& pair) const
{
return pair.first;
}
template<class TPair>
typename TPair::first_type& operator() (TPair& pair)
{
return pair.first;
}
};
static phx::function<pair_first_impl> pair_first;
int test()
{
std::map<int, std::string> mymap;
std::find_if(mymap.begin(), mymap.end(), pair_first(_1) == 1);
}
我收到一个关于pair_first_impl::result::type
的编译器错误,上面写着:
error C2825: 'TPair': must be a class or namespace when followed by '::'
see reference to class template instantiation 'pair_first_impl::result<TPair>' being compiled
with
[
TPair=const pair_first_impl (std::pair<const int,std::string> )
]
出于某种原因,它看起来像是将函数类型(?(传递到我的TPair
模板参数中,而不是直接传递到std::pair
类型中。
有人能帮我弄清楚我在这里做错了什么吗?
我通过查看协议文档的结果找到了解决方案(它与phoenix是分开的;我希望phoenix文档能解释(:
struct pair_first_impl
{
template<class> struct result;
template<class F, class TPair>
struct result<F(TPair)>
{
typedef typename boost::remove_reference<TPair>::type actual_type;
typedef typename actual_type::first_type type;
};
template<class TPair>
typename TPair::first_type const& operator() (TPair const& pair) const
{
return pair.first;
}
template<class TPair>
typename TPair::first_type& operator() (TPair& pair)
{
return pair.first;
}
};
static phx::function<pair_first_impl> pair_first;
int test()
{
std::map<int, std::string> mymap;
std::find_if(mymap.begin(), mymap.end(), pair_first(_1) == 1);
return 0;
}
问题是,我认为传递到嵌套result
结构的模板参数中的类型是第一个参数的类型,但事实并非如此。它实际上是整个函数类型。因此,必须创建result
的模板专用化,才能用于提取第一个参数的类型。然后,您可以使用它来访问对中的first_type
。
我的_1
占位符是有效的,因为在源文件的顶部,我正在执行以下操作:
using namespace boost::phoenix::placeholders;
namespace phx = boost::phoenix;
您使用了错误的占位符_1
。你需要一个真正的凤凰演员:
std::find_if(mymap.begin(), mymap.end(), pair_first(phx::placeholders::_1) == 1);
OTOH,您的函数具有不一致的result_type
协议。当你使用BOOST_SPIRIT_RESULT_OF_USE_DECLTYPE
时,这可能不会咬你。你为什么不直接用bind
呢?这将使你在没有工作的情况下得到所有正确的推断:
using namespace phx::arg_names;
void test()
{
std::map<int, std::string> mymap;
using Pair = std::pair<const int, std::string>;
std::find_if(mymap.begin(), mymap.end(), phx::bind(&Pair::first, arg1) == 1);
}
当然,如果您愿意,您可以检测配对类型。
完整代码Coliru直播
#include <boost/phoenix.hpp>
#include <algorithm>
#include <map>
namespace phx = boost::phoenix;
struct pair_first_impl
{
template<class TPair> struct result { typedef typename TPair::first_type const& type; };
template<class TPair>
typename TPair::first_type const& operator() (TPair const& pair) const {
return pair.first;
}
template<class TPair>
typename TPair::first_type& operator() (TPair& pair) {
return pair.first;
}
};
static phx::function<pair_first_impl> pair_first;
void test1()
{
using phx::placeholders::_1;
std::map<int, std::string> mymap;
std::find_if(mymap.begin(), mymap.end(), pair_first(_1) == 1);
}
void test2()
{
using Pair = std::pair<const int, std::string>;
using namespace phx::arg_names;
std::map<int, std::string> mymap;
std::find_if(mymap.begin(), mymap.end(), phx::bind(&Pair::first, arg1) == 1);
}
void test3()
{
std::map<int, std::string> mymap;
using Pair = decltype(mymap)::value_type;
using namespace phx::arg_names;
std::find_if(mymap.begin(), mymap.end(), phx::bind(&Pair::first, arg1) == 1);
}
int main()
{
test1();
test2();
test3();
}
这并不能回答您的问题,但它提供了一个基于现有实现的变通方法:(未经测试的代码(
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/phoenix/fusion/at.hpp>
...
int test()
{
std::map<int, std::string> mymap;
std::find_if(mymap.begin(), mymap.end(), boost::phoenix::at_c<0>(_1) == 1);
}
(这甚至没有提到,使用C++11 Lambdas,你不需要任何这些(
即使这有效,你的问题也是有效的。我建议进行两个实验,1( 如果是phoenix表达式,则使用enable_if
来丢弃TPair
。2( 使您的operator()
更特定于std::pair
,如下所示:
...
template<class T1, T2> // change `result` accordingly.
T1& operator() (std::pair<T1, T2>& pair)
{
return pair.first;
}
...
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了