Tho*_*ini 47 c++ const-correctness c++11
我知道答案是99.99%没有,但我认为值得一试,你永远不会知道.
void SomeFunction(int a)
{
// Here some processing happens on a, for example:
a *= 50;
a %= 10;
if(example())
a = 0;
// From this point on I want to make "a" const; I don't want to allow
// any code past this comment to modify it in any way.
}
Run Code Online (Sandbox Code Playgroud)
我可以做一些类似的东西const int b = a;,但它并不是真的相同,它会造成很多混乱.只接受C++ 0x解决方案.
编辑:另一个不那么抽象的例子,那个让我问这个问题的例子:
void OpenFile(string path)
{
boost::to_lower(path);
// I want path to be constant now
ifstream ...
}
Run Code Online (Sandbox Code Playgroud)
编辑:另一个具体的例子:在并行部分中重新获取变量的常量.
bdo*_*lan 46
您可以将代码移动a到另一个函数中:
int ComputeA(int a) {
a *= 50;
a %= 10;
if (example())
a = 0;
return a;
}
void SomeFunction(const int a_in) {
const int a = ComputeA(a_in);
// ....
}
Run Code Online (Sandbox Code Playgroud)
否则,在编译时没有很好的方法可以做到这一点.
Jar*_*Par 39
一种解决方案是将所有突变代码分解为lambda表达式.执行lambda表达式中的所有变异,并将结果分配给const int方法范围中的a.例如
void SomeFunction(const int p1) {
auto calcA = [&]() {
int a = p1;
a *= 50;
a %= 10;
if(example())
a = 0;
..
return a;
};
const int a = calcA();
...
}
Run Code Online (Sandbox Code Playgroud)
mb1*_*b14 11
我以前使用的模式是用_"隐藏"参数,因此代码变为
void SomeFunction(int _a)
{
// Here some processing happens on a, for example:
_a *= 50;
_a %= 10;
if(example())
_a = 0;
const int a = _a;
// From this point on I want to make "a" const; I don't want to allow
// any code past this comment to modify it in any way.
}
Run Code Online (Sandbox Code Playgroud)
如果需要,您还可以仅使用const变量并创建一个函数来计算a的新值.我更倾向于不"重用"变量尽可能多地使我的变量变为不可变:如果你改变了某些东西的值,那么给它一个新的名字.
void SomeFunction(const int _a)
{
const int a = preprocess(_a);
....
}
Run Code Online (Sandbox Code Playgroud)
dir*_*tly 10
为什么不将代码重构为两个单独的函数.一个返回修改的a,另一个返回此值(不改变它).
您可以将对象包裹在持有者类对象周围并使用此持有者.
template <class T>
struct Constify {
Constify(T val) : v_( val ) {}
const T& get() const { return v_; }
};
void SomeFuncion() {
Constify ci( Compute() ); // Compute returns `a`
// process with ci
}
Run Code Online (Sandbox Code Playgroud)
您的示例有一个简单的解决方法:重构.
// expect a lowercase path or use a case insensitive comparator for basic_string
void OpenFile(string const& path)
{
// I want path to be constant now
ifstream ...
}
OpenFile( boost::to_lower(path) ); // temporaries can bind to const&
Run Code Online (Sandbox Code Playgroud)
我实际上并不建议这样做,但您可以使用创意变量阴影来模拟您想要的东西:
void SomeFunction(int a)
{
// Here some processing happens on a, for example:
a *= 50;
a %= 10;
if(example())
a = 0;
{
const int b = a;
const int a = b; // New a, shadows the outside one.
// Do whatever you want inside these nested braces, "a" is now const.
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只是想避免使用其他名称,这可能是一种方法.我建议你在使用之前再三考虑.
int func ()
{
int a;
a %= 10;
const int const_a = a;
#define a const_a
a = 10; // this will cause an error, as needed.
#undef a
}
Run Code Online (Sandbox Code Playgroud)