【问题标题】:the order of member variable in class template类模板中成员变量的顺序
【发布时间】:2017-05-10 11:21:33
【问题描述】:

我已经定义了一个类模板和一个函数,

template <typename F> class Base {
    public:
        Base(F ff): f(ff) {}
        template <typename... Ps> auto operator() (Ps... ps) const -> decltype(f(ps...)) { return f(ps...); }
    private:
        // f is a pointer to function
        F* f;   
};

int f(int i, int j) 
{
    return i + j;
}

int main()
{
    using f_type = remove_reference<decltype(f)>::type;
    Base<f_type> b{f};
    b(2, 5); // [Error] no match for call to '(Base<int(int, int)>) (int, int)'
}

报告了标记错误。但是当我改变成员变量的顺序时 class Base,点赞:

template <typename F> class Base {
    private:
        // f is a pointer to function
        F* f;   
    public:
        Base(F ff): f(ff) {}
        template <typename... Ps> auto operator() (Ps... ps) const -> decltype(f(ps...)) { return f(ps...); }
};

可以编译。

这两种不同结果的原因是什么? 感谢您的宝贵时间!

【问题讨论】:

    标签: c++ templates member-variables trailing-return-type


    【解决方案1】:

    C++ 中的声明是按照它们在源代码中出现的顺序引入的。不同之处的显着例外是成员函数的主体:当在类声明中定义成员函数时,定义(而不是其声明)的行为就像函数是在类之后立即定义的一样定义。

    由于关于成员定义位置的规则适用于声明在成员函数声明中使用的名称需要声明在此刻。更改成员的位置提供了必要的声明。

    【讨论】:

    • 你的意思是在我在类中声明和定义一个成员函数之前,我要使用的成员变量必须事先定义好?还是我应该在类外定义成员函数?
    • @Vogel_guo:在哪里定义一个成员函数并不重要。但是,您在其声明中引用的名称在使用时需要知道(或者需要是依赖名称的函数)。类型名称也是如此:您不能在 [member] 函数声明中引用仅稍后定义的类型。
    • 现在我明白了。我不应该在成员函数声明中使用未定义的名称,但我可以在成员函数的定义中使用在成员函数之后定义的成员变量。对吗?
    • @Vogel_guo:在类定义范围内的成员函数定义表现得好像它们实际上是在类定义之后直接定义的一样。也就是说,inside成员函数定义对应的类如果一个完整的类型不是类定义本身的情况。
    猜你喜欢
    • 2021-07-25
    • 2022-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2017-02-19
    相关资源
    最近更新 更多