为什么几个标准运算符没有标准函子?

如何解决为什么几个标准运算符没有标准函子?

| 我们有:
std::plus
+
std::minus
-
std::multiplies
*
std::divides
/
std::modulus
%
std::negate
-
std::logical_or
||
std::logical_not
!
std::logical_and
&&
std::equal_to
==
std::not_equal_to
!=
std::less
<
std::greater
>
std::less_equal
<=
std::greater_equal
>=
) 我们没有以下函子: 30ѭ(地址)
*
(取消引用)
[]
,
按位运算符
~
&
|
^
<<
>>
++
(前缀/后缀)/
--
(前缀/后缀)
sizeof
static_cast
/
dynamic_cast
/
reinterpret_cast
/
const_cast
c风格的演员
new
/
new[]
/
delete
/
delete[]
所有成员函数指针运算符 所有复合赋值运算符。 我们没有这些是有原因的,还是仅仅是疏忽?     

解决方法

        我认为该问题最可能的答案是所包含的运算符是被认为最有用的运算符。如果没有人考虑将某些内容添加到标准库中,则不会添加任何内容。 我认为断言运算符在C ++ 0x中是无用的,因为lambda表达式优越,这很愚蠢:可以肯定的是,lambda表达式很棒而且更灵活,但是有时使用命名的functor可以使代码更简洁,更清晰,更易于理解码;此外,命名函子可以是多态的,而lambda则不能。 当然,标准库运算符是非多态的(它们是类模板,因此操作数类型是函子类型的一部分)。但是,编写自己的运算符并不特别困难,并且宏使任务非常简单:
namespace ops
{
    namespace detail
    {
        template <typename T>
        T&& declval();

        template <typename T>
        struct remove_reference      { typedef T type; }

        template <typename T>
        struct remove_reference<T&>  { typedef T type; }

        template <typename T>
        struct remove_reference<T&&> { typedef T type; }

        template <typename T>
        T&& forward(typename remove_reference<T>::type&& a)
        {
            return static_cast<T&&>(a);
        }

        template <typename T>
        T&& forward(typename remove_reference<T>::type& a)
        {
            return static_cast<T&&>(a);
        }

        template <typename T>
        struct subscript_impl
        {
            subscript_impl(T&& arg) : arg_(arg) {}

            template <typename U>
            auto operator()(U&& u) const ->
                decltype(detail::declval<U>()[detail::declval<T>()])
            {
                return u[arg_];
            }
        private:
            mutable T arg_;
        };
    }

    #define OPS_DEFINE_BINARY_OP(name,op)                              \\
        struct name                                                     \\
        {                                                               \\
            template <typename T,typename U>                           \\
            auto operator()(T&& t,U&& u) const ->                      \\
                decltype(detail::declval<T>() op detail::declval<U>())  \\
            {                                                           \\
                return detail::forward<T>(t) op detail::forward<U>(u);  \\
            }                                                           \\
        }

    OPS_DEFINE_BINARY_OP(plus,+  );
    OPS_DEFINE_BINARY_OP(minus,-  );
    OPS_DEFINE_BINARY_OP(multiplies,*  );
    OPS_DEFINE_BINARY_OP(divides,/  );
    OPS_DEFINE_BINARY_OP(modulus,%  );

    OPS_DEFINE_BINARY_OP(logical_or,|| );
    OPS_DEFINE_BINARY_OP(logical_and,&& );

    OPS_DEFINE_BINARY_OP(equal_to,== );
    OPS_DEFINE_BINARY_OP(not_equal_to,!= );
    OPS_DEFINE_BINARY_OP(less,<  );
    OPS_DEFINE_BINARY_OP(greater,>  );
    OPS_DEFINE_BINARY_OP(less_equal,<= );
    OPS_DEFINE_BINARY_OP(greater_equal,>= );

    OPS_DEFINE_BINARY_OP(bitwise_and,&  );
    OPS_DEFINE_BINARY_OP(bitwise_or,|  );
    OPS_DEFINE_BINARY_OP(bitwise_xor,^  );
    OPS_DEFINE_BINARY_OP(left_shift,<< );
    OPS_DEFINE_BINARY_OP(right_shift,>> );

    OPS_DEFINE_BINARY_OP(assign,=  );
    OPS_DEFINE_BINARY_OP(plus_assign,+= );
    OPS_DEFINE_BINARY_OP(minus_assign,-= );
    OPS_DEFINE_BINARY_OP(multiplies_assign,*= );
    OPS_DEFINE_BINARY_OP(divides_assign,/= );
    OPS_DEFINE_BINARY_OP(modulus_assign,%= );
    OPS_DEFINE_BINARY_OP(bitwise_and_assign,&= );
    OPS_DEFINE_BINARY_OP(bitwise_or_assign,|= );
    OPS_DEFINE_BINARY_OP(bitwise_xor_assign,^= );
    OPS_DEFINE_BINARY_OP(left_shift_assign,<<=);
    OPS_DEFINE_BINARY_OP(right_shift_assign,>>=);

    #define OPS_DEFINE_COMMA(),OPS_DEFINE_BINARY_OP(comma,OPS_DEFINE_COMMA());
    #undef OPS_DEFINE_COMMA

    #undef OPS_DEFINE_BINARY_OP

    #define OPS_DEFINE_UNARY_OP(name,pre_op,post_op)                  \\
    struct name                                                         \\
    {                                                                   \\
        template <typename T>                                           \\
        auto operator()(T&& t) const ->                                 \\
            decltype(pre_op detail::declval<T>() post_op)               \\
        {                                                               \\
            return pre_op detail::forward<T>(t) post_op;                \\
        }                                                               \\
    }

    OPS_DEFINE_UNARY_OP(dereference,*,);
    OPS_DEFINE_UNARY_OP(address_of,&,);
    OPS_DEFINE_UNARY_OP(unary_plus,+,);
    OPS_DEFINE_UNARY_OP(logical_not,!,);
    OPS_DEFINE_UNARY_OP(negate,-,);
    OPS_DEFINE_UNARY_OP(bitwise_not,~,);
    OPS_DEFINE_UNARY_OP(prefix_increment,++,);
    OPS_DEFINE_UNARY_OP(postfix_increment,++);
    OPS_DEFINE_UNARY_OP(prefix_decrement,--,);
    OPS_DEFINE_UNARY_OP(postfix_decrement,--);
    OPS_DEFINE_UNARY_OP(call,());
    OPS_DEFINE_UNARY_OP(throw_expr,throw,);
    OPS_DEFINE_UNARY_OP(sizeof_expr,sizeof,);

    #undef OPS_DEFINE_UNARY_OP

    template <typename T>
    detail::subscript_impl<T> subscript(T&& arg)
    {
        return detail::subscript_impl<T>(detail::forward<T>(arg));
    }

    #define OPS_DEFINE_CAST_OP(name,op)                                \\
        template <typename Target>                                      \\
        struct name                                                     \\
        {                                                               \\
            template <typename Source>                                  \\
            Target operator()(Source&& source) const                    \\
            {                                                           \\
                return op<Target>(source);                              \\
            }                                                           \\
        }

    OPS_DEFINE_CAST_OP(const_cast_to,const_cast      );
    OPS_DEFINE_CAST_OP(dynamic_cast_to,dynamic_cast    );
    OPS_DEFINE_CAST_OP(reinterpret_cast_to,reinterpret_cast);
    OPS_DEFINE_CAST_OP(static_cast_to,static_cast     );

    #undef OPS_DEFINE_CAST_OP

    template <typename C,typename M,M C::*PointerToMember>
    struct get_data_member
    {
        template <typename T>
        auto operator()(T&& arg) const ->
            decltype(detail::declval<T>().*PointerToMember)
        {
            return arg.*PointerToMember;
        }
    };

    template <typename C,M C::*PointerToMember>
    struct get_data_member_via_pointer
    {
        template <typename T>
        auto operator()(T&& arg) const ->
            decltype(detail::declval<T>()->*PointerToMember)
        {
            return arg->*PointerToMember;
        }
    };
}
我已经省略了
new
delete
(以及它们的各种形式),因为用它们编写异常安全代码非常困难:-)。
call
的实现仅限于无效的ѭ55;重载;使用可变参数模板,您也许可以扩展它以支持更大范围的重载,但实际上,最好使用lambda表达式或库(如
std::bind
)来处理更高级的调用方案。 ѭ57和ѭ58实现也是如此。 提供了剩余的可重载运算符,甚至是愚蠢的诸如
sizeof
throw
。 [以上代码是独立的;不需要标准库头。我承认对于右值引用我还是有点菜鸟,所以如果我对它们做错了事,希望有人能告诉我。]     ,        原因可能是大多数开发人员不需要它们。其他人使用Boost.Lambda,其中大多数都在那里。     ,        极有可能的是,标准委员会中没有人认为它们会有用。有了C ++ 0x的lambda支持,它们都没有用。 编辑: 我并不是说他们没有用,更多的是委员会上的任何人都没有真正想到过这种用处。     ,        在C ++ 0x中添加了按位运算符。我还发现not_equal_to已经存在。 其他(例如sizeof和某些强制转换)是编译时运算符,因此在函子中用处不大。 new和delete在分配器中抽象。我们需要更多吗?     ,        say47ѭ每个发言都没有函子,但是默认分配器确实将请求传递给pass47ѭ。由于两者已链接,因此也涵盖了covers49ѭ。 从那里开始,我认为这些仿函数并不是真的要被视为“您传递给
for_each
的东西,而是”您可能需要根据具体情况专门研究的东西。” 从列表中删除
new
[和家族],基本上您可以进行一堆除了语言指定之外没有实际意义的操作。如果采用对象的地址,则实际上只有一件事要发生:您将获得该对象的地址。可能会改变,但不会改变。因此,实际上并不需要通过标准函子来专门化该行为。您可以只使用
&
并信任运算符重载来执行此操作。但是\“ add \”或\“ compare \”的含义可能会在程序执行过程中发生变化,因此提供一种实现方法的优点。 这也包括复合赋值运算符;它们的含义与它们的两个部分相关,因此,如果您需要
std::add_assign
,就可以退回到
std::add
[和
operator =
,这是您列表中没有的]。 按位运算符介于两者之间;我可以以任何一种方式看到他们的论点。     ,列出的所有参数都是两个参数的函子。并非以下所有内容。实际上,只有
>>
<<
&
|
!=
满足该标准,并且就函子而言,它们的用处不大。强制转换尤其是模板,这使得它们的使用性降低了。     

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

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-