【问题标题】:std::declval vs crtp, cannot deduce method return type from incomplete typestd::declval vs crtp,无法从不完整类型推断方法返回类型
【发布时间】:2019-06-07 16:07:26
【问题描述】:

我正在尝试做这样的事情(在 c++11 中):

#include <utility>

template <typename T>
struct base {
    using type = decltype( std::declval<T>().foo() );
};

struct bar : base<bar> {
    int foo() { return 42;}
};

int main() {
    bar::type x;
}

失败了

prog.cc: In instantiation of 'struct base<bar>':
prog.cc:8:14:   required from here
prog.cc:5:46: error: invalid use of incomplete type 'struct bar'
     using type = decltype( std::declval<T>().foo() );
                            ~~~~~~~~~~~~~~~~~~^~~
prog.cc:8:8: note: forward declaration of 'struct bar'
 struct bar : base<bar> {
        ^~~

如何在 base 中为 bar::foo 的返回类型声明别名?不可能吗?

这个问题似乎相当相关:Special behavior for decltype of call operator for incomplete types,尽管我无法将那里给出的答案应用于我的案例。

【问题讨论】:

    标签: c++ c++11 decltype crtp declval


    【解决方案1】:

    您可以将type 设为模板类型别名,以便用户在bar 的定义可用后对其进行实例化。这会将最终语法从bar::type 更改为bar::type&lt;&gt;

    template <typename T>
    struct base {
        template <typename G = T>
        using type = decltype( std::declval<G>().foo() );
    };
    
    struct bar : base<bar> {
        int foo() { return 42;}
    };
    
    int main() {
        bar::type<> x;
    }
    

    live example on godbolt.org

    【讨论】:

    • 我想现在我也理解了我链接的答案中的推理:) 我不太喜欢bar::type&lt;&gt;,但我可以忍受
    • 不幸的是,type&lt;&gt; 在类范围内没有那么有用。例如,如果不使用类似的 G = T 技巧,则不能为 basebar 的成员函数编写 type&lt;&gt; foo2();
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 2018-12-20
    • 2021-06-11
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2021-09-20
    相关资源
    最近更新 更多