【问题标题】:which identifiers are available to lambda in constructor initializer list构造函数初始值设定项列表中的 lambda 可以使用哪些标识符
【发布时间】:2012-07-02 07:04:51
【问题描述】:

更重要的是,这段代码有什么问题:

#include <assert.h>
#include <functional>
using namespace std;

    template< class BaseObjectId >
    class Check
    {
    protected:
        Check( function<bool()> const f ) { assert( f() ); }
    };

    template< int tpMinValue, int tpMaxValue >
    class IntegerSubrange
        : private Check< IntegerSubrange< tpMinValue, tpMaxValue > >
    {
    private:
        int     value_;

    public:
        enum :int { minValue = tpMinValue, maxValue = tpMaxValue };

        static bool rangeContains( int const x )
        {
            return (minValue <= x && x <= maxValue);
        }

        operator int() const
        {
            return value_;
        }

        void operator/=( int const rhs )
        {
            value_ /= rhs;
            assert( rangeContains( value_ ) );
        }

        explicit IntegerSubrange( int const value )
            : Check< IntegerSubrange< tpMinValue, tpMaxValue > >(
                [=]() -> bool { return rangeContains( value ); }
                )
            , value_( value )
        {}
    };

int main() {}

Visual C++ 报告一个语法错误

foo.cpp foo.cpp(41):错误 C2059:语法错误:')' foo.cpp(44) : 请参阅正在编译的类模板实例化 'IntegerSubrange' 的参考 foo.cpp(42):错误 C2059:语法错误:',' foo.cpp(43) : 错误 C2334: '{' 之前的意外标记;跳过明显的函数体

【问题讨论】:

  • 啊,那我需要更新我的 g++。我也会用visual c ++ 11检查! 用 Visual C++ 11 编译得很好,我简直不敢相信
  • @Griwes:g++ 4.6.3 比 4.6.1 更新,4.6.1 编译 lambdas 就好了。
  • @Cheersandhth.-Alf,EitanT 链接了一个证明 4.3.4 无法编译它的证据 - 我指的是那个 - 现在已删除 - 评论。
  • 其实compiles on gcc-4.5.1也是...

标签: c++ constructor lambda


【解决方案1】:

总结 cmets:提问者的代码是有效的。 显然,一些早于 GCC 4.4 或 Visual C++ 2011 的编译器会拒绝它,因为这些编译器对 C++11 风格的支持不完整拉姆达斯。但是现代编译器(当然还有任何声称支持新 C++11 标准的编译器)应该可以很好地处理它。

从字面上回答您的问题:在 ctor-initializer-list 中,可以使用相同的标识符(并且指代相同的事物),就像您将它们移到花括号内时所指的那样构造函数本身。特别是,这意味着您可以这样做

class C {
    const char *p_ = "foo";
    char c_;
    C(int): p_(__func__) { }      // referring to "__func__"
    C(double): c_(*this->p_) { }  // referring to "this"
};

以下是标准对该主题的看法:

mem-initializerexpression-listbraced-init-list 中的名称 在构造函数的范围内进行评估 mem-initializer 被指定。 ... [注意: 因为 mem-initializer 是 [sic] 在构造函数的范围内评估的,this 指针可以是 在 mem-initializerexpression-list 中使用来指代 正在初始化的对象。 —尾注]   (N3337 §12.6.2 #12)

【讨论】:

  • 很高兴为您提供帮助。我经常搜索有趣的未回答问题,所以如果我看到一个有趣的问题在 cmets 中得到了“回答”,但在真正的“答案”中没有,我会经常写一个,只是为了将其从搜索结果中删除。 :)
猜你喜欢
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多