使用类成员函数对象推断成员函数返回类型。

时间:2022-06-02 19:26:51

Edit: I feel kind of silly now. The posted code actually works with ???=decltype(acc(base(i)))... The error was something else - highly confusing though. I will post a new question about that. Thank you for your help.

我现在觉得有点傻。发布的代码实际使用的是???=decltype(acc(base(i)))……这个错误是其他的东西——非常令人困惑。我将提出一个新的问题。谢谢你的帮助。


I have some code like this:

我有一些这样的代码:

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

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

How do I get the correct return type?

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

I tried with decltype(acc(base(i))) but this gives an error (using GCC 4.6.3):

我尝试使用decltype(acc(base(I))),但这给出了一个错误(使用GCC 4.6.3):

there are no arguments to ‘base’ that depend on a template parameter, so a declaration of ‘base’ must be available

不存在依赖于模板参数的“base”参数,因此必须有“base”声明。

1 个解决方案

#1


2  

I have been troubled for hours or days around such problems. Typically gcc wants this-> but clang does not. In some cases Foo:: also helps but there have been cases where I have given up using the member names. The following is only using the type names and (though more verbose) I think will not have any problems with either:

我为这些问题苦恼了好几个小时。通常gcc想要这个->但是clang不需要。在某些情况下,Foo::也有帮助,但是在某些情况下,我已经放弃使用成员名称。下面仅使用类型名称,(尽管更详细)我认为这两种方法都不会有任何问题:

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)); }
};

More generally, whenever decltype(member_name) is causing problems, you can safely use decltype(std::declval<member_type>()) where member_type is const-qualified if the member function using it is const.

更一般地说,当decltype(member_name)出现问题时,您可以安全地使用decltype(std::declval ()),如果成员函数使用它,则member_type为const。

Even more generally, if you have a member function that is &&, & or const& qualified, use member_type, member_type& or const member_type& respectively in such expressions.

更一般地说,如果您有一个成员函数,即&& &或const&qualified,则分别使用member_type、member_type&或const member_type&分别在这样的表达式中。

I have never looked into what the standard says but in practice compilers treat expressions differently in trailing return types and inside function definitions when it comes to class members.

我从来没有研究过标准所说的内容,但是在实践中,编译器在处理类成员时,在跟踪返回类型和内部函数定义中处理表达式的方式是不同的。

#1


2  

I have been troubled for hours or days around such problems. Typically gcc wants this-> but clang does not. In some cases Foo:: also helps but there have been cases where I have given up using the member names. The following is only using the type names and (though more verbose) I think will not have any problems with either:

我为这些问题苦恼了好几个小时。通常gcc想要这个->但是clang不需要。在某些情况下,Foo::也有帮助,但是在某些情况下,我已经放弃使用成员名称。下面仅使用类型名称,(尽管更详细)我认为这两种方法都不会有任何问题:

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)); }
};

More generally, whenever decltype(member_name) is causing problems, you can safely use decltype(std::declval<member_type>()) where member_type is const-qualified if the member function using it is const.

更一般地说,当decltype(member_name)出现问题时,您可以安全地使用decltype(std::declval ()),如果成员函数使用它,则member_type为const。

Even more generally, if you have a member function that is &&, & or const& qualified, use member_type, member_type& or const member_type& respectively in such expressions.

更一般地说,如果您有一个成员函数,即&& &或const&qualified,则分别使用member_type、member_type&或const member_type&分别在这样的表达式中。

I have never looked into what the standard says but in practice compilers treat expressions differently in trailing return types and inside function definitions when it comes to class members.

我从来没有研究过标准所说的内容,但是在实践中,编译器在处理类成员时,在跟踪返回类型和内部函数定义中处理表达式的方式是不同的。