使用 mpl 对现有元功能进行部分特化
也许我今天不在场,但我想知道如何让它发挥作用。 我想部分专业化 boost 库中的 range_mutable_iterator 和 range_const_iterator ,但仅限于我宁愿避免明确提及的特定类型,而是仅在启用_if 测试标准通过时才选择部分专业化。
我当前正在使用 MSVC 2008,但收到以下错误:ArrayType
:模板参数未在部分专业化中使用或可推导
类型
range_mutable_iterator<
typename enable_if<
mpl::and_<
mpl::has_key<some_type_map, typename remove_const<T>::type>,
mpl::not_<is_const<T> >
>,
ArrayType
>::type
>
使用 STLFilt,请注意对 T 而不是 ArrayType 的奇怪引用,我猜 STLFilt 说它可以'不明白 T == ArrayType..?这就是我现在所拥有的:
namespace boost {
template<class ArrayType>
struct range_mutable_iterator<
typename enable_if<
mpl::and_<
mpl::has_key<some_type_map, typename remove_const<ArrayType>::type>,
mpl::not_<is_const<ArrayType> >
>,/*and_*/
ArrayType
>::type/*enable_if*/
>
{
typedef MyArrayIterator<
typename mpl::at<some_other_type_map,
typename mpl::at<yet_another_type_map,ArrayType>::type
>::type/*at*/
>/*MyArrayIterator*/ type;
};
}
让 range_begin/range_end 工作目前不是问题,目标是让线条工作看起来像这样:
ThirdPartyArrayClass blah;
MyArrayAdapter<ThirdPartyArrayClass>::iterator iter = boost::begin(blah);
编辑:在尝试了我从这个答案中编辑出的不同方法之后,我开始接受在这种情况下部分专业化是不可能的,因此我使用了一种不同的方法,其中涉及完全专业化和大量使用 Boost.Preprocessor。
Maybe I'm not all there today, but I'm wondering how to get this to work.
I'd like to partially specialize range_mutable_iterator and range_const_iterator from the boost library but only for specific types that I'd rather avoid mentioning explicitly, instead only letting the partial specialization be chosen if the enable_if test criteria pass.
I'm currently using MSVC 2008 and am receiving the following error:ArrayType
: template parameter not used or deducible in partial specialization
on type
range_mutable_iterator<
typename enable_if<
mpl::and_<
mpl::has_key<some_type_map, typename remove_const<T>::type>,
mpl::not_<is_const<T> >
>,
ArrayType
>::type
>
Using STLFilt, notice the odd reference to T instead of ArrayType, I'm guessing STLFilt is saying it can't figure out that T == ArrayType..? Here's what I have right now:
namespace boost {
template<class ArrayType>
struct range_mutable_iterator<
typename enable_if<
mpl::and_<
mpl::has_key<some_type_map, typename remove_const<ArrayType>::type>,
mpl::not_<is_const<ArrayType> >
>,/*and_*/
ArrayType
>::type/*enable_if*/
>
{
typedef MyArrayIterator<
typename mpl::at<some_other_type_map,
typename mpl::at<yet_another_type_map,ArrayType>::type
>::type/*at*/
>/*MyArrayIterator*/ type;
};
}
Getting range_begin/range_end working isn't currently an issue, the goal is to have a line work that looks like this:
ThirdPartyArrayClass blah;
MyArrayAdapter<ThirdPartyArrayClass>::iterator iter = boost::begin(blah);
Edit: After having tried a different approach which I've edited out of this answer, I came to accept that partial specialization in this case just isn't possible, so I've used a different approach which involves full specialization and heavy use of Boost.Preprocessor.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了部分特化模板,编译器必须将实际模板参数与现有特化相匹配,以选择最佳匹配。如果特化中的模板参数仅用作依赖类型的(模板)参数,则这是不可能的。所以,编译器会抱怨,这是正确的。您唯一能做的就是以某种方式专门化您的具体
ThirdPartyArrayClass
类型。In order to partially specialize a template the compiler must match the actual template arguments to the existing specializations, with the aim to select the best match. This is just not possible if the template argument in the specialization is used just as the (template) parameter to a dependent type. So, the compiler complains, and rightly so. The only thing you can do is to somehow specialize on your concrete
ThirdPartyArrayClass
type.