使用 mpl 对现有元功能进行部分特化

发布于 2024-09-12 12:28:37 字数 1440 浏览 8 评论 0原文

也许我今天不在场,但我想知道如何让它发挥作用。 我想部分专业化 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜未央樱花落 2024-09-19 12:28:40

为了部分特化模板,编译器必须将实际模板参数与现有特化相匹配,以选择最佳匹配。如果特化中的模板参数仅用作依赖类型的(模板)参数,则这是不可能的。所以,编译器会抱怨,这是正确的。您唯一能做的就是以某种方式专门化您的具体 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文