【问题标题】:Deduce member function return type using a class member function object使用类成员函数对象推断成员函数返回类型
【发布时间】:2014-04-16 16:32:12
【问题描述】:

编辑:我现在觉得有点傻。发布的代码实际上适用于 ???=decltype(acc(base(i)))... 错误是别的东西 - 虽然非常令人困惑。我会就此发布a new question。感谢您的帮助。


我有一些这样的代码:

template<typename Base, typename Acc>
struct Foo
{
    Base base;
    Acc acc;

    auto operator()(unsigned i) const -> decltype(???) // what is ???
    { return acc(base(i)); }
};

如何获得正确的返回类型?

我尝试使用 decltype(acc(base(i))) 但这会产生错误(使用 GCC 4.6.3):

“base”没有依赖于模板参数的参数, 所以必须有一个“base”声明

【问题讨论】:

  • 作为一种变通方法,请尝试decltype(acc(this-&gt;base(i))) 甚至decltype(this-&gt;acc(this-&gt;base(i)))
  • 尝试更新的 GCC。我在 Ubuntu 中使用 GCC 4.8.1 进行了尝试——它有效
  • 我相信decltype(acc(base(i))) 是正确的(除非问题出在您未显示的某些代码中)但 gcc 4.6.3 太旧而无法正确实现(它适用于 gcc 4.8. 1)。尝试更新您的编译器或 Daniel Frey 给出的解决方法。
  • 您可以尝试“完全限定” ???用 Foo::... 看看它是否欣赏从头开始的方法
  • @DanielFrey 虽然这种解决方法对于 gcc 来说是可以的,但大多数时候它对 clang 来说是有问题的。我一直对此感到困扰,我通常会找到一些完全不同的解决方案,没有任何decltype

标签: c++ templates c++11 decltype


【解决方案1】:

我已经为这些问题困扰了几个小时或几天。通常 gcc 想要 this-&gt; 但 clang 不想要。在某些情况下Foo:: 也有帮助,但在某些情况下我已经放弃使用成员名称。以下仅使用 type 名称和(虽然更冗长)我认为不会有任何问题:

template<typename Base, typename Acc>
struct Foo
{
    Base base;
    Acc acc;

    template<typename S>
    using result = typename std::result_of<S>::type;

    auto operator()(unsigned i) const
    -> result<const Acc(result<const Base(unsigned)>)>
        { return acc(base(i)); }
};

更一般地,每当decltype(member_name) 引起问题时,您可以安全地使用decltype(std::declval&lt;member_type&gt;()),其中member_typeconst,如果使用它的成员函数是const,则它是合格的。

更一般地说,如果您的成员函数是 &amp;&amp;&amp;const&amp;,则在此类表达式中分别使用 member_typemember_type&amp;const member_type&amp;

我从未研究过标准的内容,但在实践中,当涉及到类成员时,编译器在尾随返回类型和内部函数定义中对表达式的处理方式不同。

【讨论】:

  • 小心constoperator()(unsigned i)const,因此是baseacc。我想你需要result&lt;const Acc(result&lt;const Base(unsigned)&gt;)&gt;。无论如何+1 :)
  • @DanielFrey 谢谢,已更正。事实上,每当我有一个保存数据的通用函数对象时,我最终都会得到operator()&amp;&amp;&amp;const&amp;)的 3 个重载,并且所有类型都会根据需要进行调整。
  • 感谢您的回答!我明天上班检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多