C++成员操作符的enable_if(或解决方法)

发布于 2024-10-31 17:39:06 字数 397 浏览 1 评论 0原文

template<typename T>
struct foo
{
    T* p;
    foo(T* x) : p(x) {}
    ~foo() { if(p) delete p; }
    T& operator*() const { return *p; }
};

int main()
{
    foo<int>  i(new int);
    foo<void> v(new int);   // <= illegal use of type 'void'
}

如果 T = void 那么我不想实现运算符*()。我怎样才能实现这个目标?我不想专门化这个类,因为我的类中有很多其他方法。

PS:请注意,这只是一个解释我的问题的例子。

template<typename T>
struct foo
{
    T* p;
    foo(T* x) : p(x) {}
    ~foo() { if(p) delete p; }
    T& operator*() const { return *p; }
};

int main()
{
    foo<int>  i(new int);
    foo<void> v(new int);   // <= illegal use of type 'void'
}

If T = void then I don't want to implement the operator*(). How can I achieve this? I don't want to specialize the class, because there are many other methods in my class.

PS: Please note that this is just an example to explain my issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(5

凝望流年 2024-11-07 17:39:06

您可以将所有其他方法(与 T==void 配合良好)移至基类中,并让 foo 从它派生。然后 foo 可以专门化为不声明 T==voidoperator*

template <typename T>
struct foobase {

  T* p;
  foobase(T* x) : p(x) {}
  ~foobase() { if(p) delete p; }

};

template <typename T>
struct foo : foobase<T> {
  T& operator*() const { return *p; }
};

template<> 
struct foo<void> : foobase<void> {

};

You can move all the other methods (which play well with T==void) into a base class and make foo derive from it. Then foo can be specialized to not declare the operator* for T==void

template <typename T>
struct foobase {

  T* p;
  foobase(T* x) : p(x) {}
  ~foobase() { if(p) delete p; }

};

template <typename T>
struct foo : foobase<T> {
  T& operator*() const { return *p; }
};

template<> 
struct foo<void> : foobase<void> {

};
冰雪梦之恋 2024-11-07 17:39:06

C++11 标准为 std::unique_ptr 解决了这个问题,如下所示:

typename std::add_lvalue_reference<T>::type
    operator*() const { return *p; }

The C++11 standard solved this for std::unique_ptr like so:

typename std::add_lvalue_reference<T>::type
    operator*() const { return *p; }
我们的影子 2024-11-07 17:39:06

像这样:

template<typename T>
struct foo_base
{
    T* p;
    foo(T* x) : p(x) {}
    ~foo() { if(p) delete p; }

    // other methods …
};

template<typename T>
struct foo : foo_base<T>
{
    T& operator*() const { return *p; }
};

template<>
struct foo<void> : foo_base<void>
{
};

Like that:

template<typename T>
struct foo_base
{
    T* p;
    foo(T* x) : p(x) {}
    ~foo() { if(p) delete p; }

    // other methods …
};

template<typename T>
struct foo : foo_base<T>
{
    T& operator*() const { return *p; }
};

template<>
struct foo<void> : foo_base<void>
{
};
遗忘曾经 2024-11-07 17:39:06

怎么样?

typename disable_if<is_void<T>, T>::type& operator* () const { return *p;}

我在这里遗漏了一些明显的东西

How about

typename disable_if<is_void<T>, T>::type& operator* () const { return *p;}

or am I missing something obvious here?

灼痛 2024-11-07 17:39:06

这个解决方案有何特点:

template<typename T>
struct foo
{
    T* p;
    foo(T* x) : p(x) {}
    ~foo() { if(p) delete p; }

    template<typename U> struct impl { U& deref(U* p) { return *p; } };
    template<> struct impl<void> { void deref(void* p) { } };

    typename boost::conditional<std::is_void<T>::value, T, typename std::add_reference<T>::type>::type operator*() const
    {
        static_assert(!std::is_void<T>::value, "illegal use of type 'void'");
        return impl<T>().deref(p); 
    }
};

What's about this solution:

template<typename T>
struct foo
{
    T* p;
    foo(T* x) : p(x) {}
    ~foo() { if(p) delete p; }

    template<typename U> struct impl { U& deref(U* p) { return *p; } };
    template<> struct impl<void> { void deref(void* p) { } };

    typename boost::conditional<std::is_void<T>::value, T, typename std::add_reference<T>::type>::type operator*() const
    {
        static_assert(!std::is_void<T>::value, "illegal use of type 'void'");
        return impl<T>().deref(p); 
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文