更重要的是,这段代码有什么问题:
#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/