更重要的是,这段代码出了什么问题:
#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
答案 0 :(得分: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的表达式列表或 braced-init-list 中的名称 在构造函数的范围内进行评估 指定了 mem-initializer 。 ... [注意:因为 mem-initializer 是[ sic ]在构造函数的范围内计算,
this
指针可以是 用于 mem-initializer 的表达式列表中以引用 对象被初始化。 - 结束记录] (N3337 §12.6.2 #12)