8

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

#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: '{' 之前的意外标记;跳过明显的函数体
4

1 回答 1

4

总结评论:提问者的代码是有效的。显然,一些早于 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"
};

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

mem-initializer的expression-listbraced-init-list中的名称在为其指定mem-initializer 的构造函数的范围内进行评估 。... [注意:因为mem-initializer 在构造函数的范围内评估的,所以指针可以在mem-initializer的表达式列表中使用,以引用正在初始化的对象。—<em>尾注]     (N3337 §12.6.2 #12)this

于 2012-09-14T18:04:24.500 回答