c++ - 哪些标识符可用于构造函数初始化列表中的 lambda

标签 c++ constructor lambda

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

#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) : error C2059: syntax error : ')'
        foo.cpp(44) : see reference to class template instantiation 'IntegerSubrange' being compiled
foo.cpp(42) : error C2059: syntax error : ','
foo.cpp(43) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body

最佳答案

总结一下评论:提问者的代码是有效的。显然一些早于 GCC 4.4 或 Visual C++ 2011 的编译器会拒绝它,因为这些编译器对 C++11 风格的支持不完整 lambda 。但是现代编译器(当然还有任何声称支持新 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"
};

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

Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified. ... [Note: Because the mem-initializer are [sic] evaluated in the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized. —end note]    (N3337 §12.6.2 #12)

关于c++ - 哪些标识符可用于构造函数初始化列表中的 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11283977/

相关文章:

c++ - 项目的库位置

c++ - 实现外部mergesort。如何开始?

java - C++ 的类变量是否可以像 Java 一样在没有构造函数的情况下进行初始化?

Java readObject 和继承的转换

java - 在 Java8 中引入 lambda 会改变或影响哪种 GoF 设计模式?

用于保存无法在构造函数中初始化的成员的 C++ 类型

c++ - 计算每秒时钟数

c++ - 仅在 C++ 中声明默认构造函数

c# - 将数据表转换为 IList c#

android - 错误 :Jack is required to support java 8 language features. 启用 Jack 或删除 sourceCompatibility JavaVersion.VERSION_1_8