【问题标题】:How Can I Use result_of Instead of decltype?如何使用 result_of 而不是 decltype?
【发布时间】:2015-06-02 11:43:30
【问题描述】:

this answer 我创建了一个类型特征:

template<typename T>
using to_string_t = decltype(to_string(declval<T>()));

这很好用,但我最初打算使用result_of,现在我不知道该怎么做,这让我很恼火。

我正在尝试将上面的行替换为以下内容:

template<typename T>
using to_string_t = result_of<to_string(T)>;

但是我得到一个编译器错误:

错误 C2275:“T”:非法将此类型用作表达式
注意:参见“T”的声明
错误 C2974:“std::result_of”:“_Fty”的模板参数无效,需要键入

我尝试了几个其他输入 result_of 都没有成功,谁能帮我理解 result_of 在这里期待什么参数?

【问题讨论】:

    标签: c++ typetraits overloading decltype result-of


    【解决方案1】:

    让我们修补它。 std::result_of 只需要类型,它的结果应该从它的 type 内部 typedef 中检索,你需要 typename 来访问所说的 typedef,因为它依赖于模板参数。

    template<typename T>
    using to_string_t = typename std::result_of<decltype(std::to_string)(T)>::type;
                        ^^^^^^^^                ^^^^^^^^                    ^^^^^^
    

    或者在 C++14 中,您可以删除 ::typetypename

    template<typename T>
    using to_string_t = std::result_of_t<decltype(std::to_string)(T)>;
                                      ^^
    

    好的?

    main.cpp:5:68: error: decltype cannot resolve address of overloaded function
    

    对,std::to_string 已重载,因此我们需要通过将其强制转换为其中一个重载来消除歧义。

    template<typename T>
    using to_string_t = typename std::result_of<decltype(static_cast<
    

    等一下。我们需要它的返回类型来表达转换的目标类型。我们又回到了起点。

    std::result_of 无法处理重载函数,因为在重载解决之前,函数没有确定的类型。 decltype 是这里唯一的解决方案,因为它确实应用了重载决议。

    如果您想知道std::result_of 有什么用处,鉴于上述限制:它用于重载函子,即多次重载() 运算符的类。由于类的类型是已知的,并且不依赖于调用参数,std::result_of 有效。

    ...但是std::to_string 不应该总是返回std::string 吗??

    【讨论】:

    • decltype(decltype(std::to_string(declval&lt;T&gt;())(declval&lt;T&gt;()) :)
    • @bolov 缺少右括号,但即便如此,您仍将 std::string 作为函数调用。此外,这很难避免decltype/declval:p
    • sry:这里是:std::result_of_t&lt;decltype(std::to_string(std::declval&lt;T&gt;())(std::declval&lt;T&gt;()))&gt;(现已测试,请注意)。但是是的,它使用 decltype 来获取 to_string 的结果,以便创建用于 result_of 的类型来获取...to_string 的结果。但是...它使用result_of :))
    • @bolov 实在无法反驳... :p
    • @JonathanMee 检索result_of 需要的函数类型的唯一方法是解决重载问题。要么我们通过强制转换来手动执行此操作(但随后我们提供了我们正在搜索的信息),要么我们使用decltype 在其未评估的上下文中完成这项工作。也就是说,我们又回到了第 1 格。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    相关资源
    最近更新 更多