【问题标题】:Can I use boost::enable_if on a member function?我可以在成员函数上使用 boost::enable_if 吗?
【发布时间】:2011-06-20 08:05:10
【问题描述】:

我正在编写一个模板类,我想允许一个额外的方法只存在于某个模板类型。目前该方法适用于所有模板类型,但会导致所有其他类型的编译错误。

更复杂的是,它是一个重载的 operator()。不确定我想要做的事情是否真的可以在这里。

这是我现在拥有的:

template<typename T, typename BASE>
class MyClass  : public BASE
{
public:

    typename T& operator() (const Utility1<BASE>& foo);
    typename T const& operator() (const Utility2<BASE>& foo) const;
};

我希望T&amp; 版本始终可用,但T const&amp; 版本仅在Utility2&lt;BASE&gt; 有效时可用。目前,这两种方法都存在,但如果 Utility2&lt;BASE&gt; 无效,则尝试使用 const 版本会产生奇怪的编译错误。我宁愿有一个明智的错误,甚至是“没有这样的成员函数”错误。

这可能吗?

编辑:在阅读了 boost 文档之后,这是我想出的,它似乎有效:

template<typename T, typename BASE>
class MyClass  : public BASE
{
public:

    typename T& operator() (const Utility1<BASE>& foo);

    template<typename U>
    typename boost::enable_if<boost::is_same<Utility2<BASE>, U>, T>::type const &
    operator() (const U& foo) const;
};

因此,除非有人尝试将它与 Utility2 一起使用,否则该方法不存在,并且他们只能创建一个 Utility2,如果它对该 BASE 类型有效。但是当它对该 BASE 类型无效时,MyClass 不会浪费时间创建访问器方法。

【问题讨论】:

  • Utility2&lt;BASE&gt; 是“有效”是什么意思?
  • Utility2 尝试调用 BASE 上的方法。只有一种类型的 BASE 实际上具有该方法。
  • 如果你仍然想要编译器错误,静态断言可能是一个更好的主意。
  • 是的,我更喜欢编译错误。基本上,除了非常特殊的情况外,没有人应该尝试使用Utility2。最好在编译时发现这种错误。

标签: c++ templates boost enable-if


【解决方案1】:

是的,这是可能的,但不能直接使用类模板参数。 boost::enable_if 只能与方法本身的模板参数一起使用。所以,用一点 typedef 用法:

template<typename T, typename BASE>
class MyClass  : public BASE
{
public:
  typedef Utility2<BASE> util;

  typename T& operator() (const Utility1<BASE>& foo);

  template<typename U>
  typename boost::enable_if<boost::is_same<util, U>, T>::type const &
  operator() (const U& foo) const;
};

这是可行的,因为 Utility2 只能从某个 BASE 类型创建。因此,如果 BASE 类型是其他类型,则 operator() 的 const 版本将不存在。

所以,这是一件非常微不足道的事情。它对我没有多大好处。但这很好。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    相关资源
    最近更新 更多