微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 在仅在某些情况下使用decltype的模板中实例化函数定义

作为理解C 0x的练习,我试图创建一个包含某些模板化类型指针的C类:
template <typename T>
class Wrapper {
    T *t;
    /* ... */
};

在Wrapper类中,我想公开T可以通过Wrapper类实现的任何重载操作符.包装器本身只是将函数调用转发给底层的t对象.

template <typename U>
auto operator+(U &u) -> decltype (*t + u) {
    return *t + u;
}

问题在于我不希望Wrapper暴露T可能无法实现的运算符.例如,如果T没有实现运算符,那么Wrapper也不应该公开运算符.

在运算符(和任何二元运算)的情况下,一切都运行,因为运算符必然成为模板函数,因此仅在我们尝试调用时实例化,例如Wrapper :: operator.

然而,在一元运算符(例如)的情况下,没有明确的方法来保护运算符,以便如果T实现运算符则实例化它.例如,这个类中的运算符的天真实现

auto operator++() -> decltype(++(*t)) {
    return ++(*t);
}

无法编译不支持operator()的T.

根据我对标准的理解,如果我们有以下使用Wrapper的代码

class X { };
Wrapper<X> w;

我们将实例化Wrapper和Wrapper :: operator()的声明,但不是它的定义,除非我们调用它(或显式实例化它).通常情况下这是可以的,因为X ::运算符的使用仅出现在Wrapper :: operator()的定义中.但是,由于decltype,我们在声明中使用X ::运算符,以便typechecker检查是否存在X ::运算符,从而失败.

我们可以定义operator()(通常是任何使用decltype的转发函数)和实例化的属性iff底层对象是否也支持operator()?或者给出模板实例化和decltype的语义,这是不可能完成的?

解决方法

您可以将运算符声明为非成员模板:
template <typename T>
auto operator++(Wrapper<T>& arg) -> decltype(++*arg.t) {
    return ++*arg.t;
}

原文地址:https://www.jb51.cc/c/111487.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐