我知道答案是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.
}
我可以使用const int b = a;
做一些类似的事情,但它并不是真的相同而且会造成很多混乱。只接受C ++ 0x解决方案。
编辑:另一个不那么抽象的例子,那个让我问这个问题的例子:
void OpenFile(string path)
{
boost::to_lower(path);
// I want path to be constant now
ifstream ...
}
编辑:另一个具体示例:Recapture const-ness on variables in a parallel section。
答案 0 :(得分: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);
// ....
}
否则,在编译时没有很好的方法。
答案 1 :(得分:38)
一种解决方案是将所有突变代码分解为lambda表达式。执行lambda表达式中的所有变异,并将结果分配给方法范围中的const int
。例如
void SomeFunction(const int p1) {
auto calcA = [&]() {
int a = p1;
a *= 50;
a %= 10;
if(example())
a = 0;
..
return a;
};
const int a = calcA();
...
}
答案 2 :(得分: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.
}
如果需要,您还可以仅使用const变量并创建一个函数来计算a的新值。我更倾向于不“重用”变量尽可能多地使我的变量变为不可变:如果你改变了某些东西的值,那么给它一个新的名字。
void SomeFunction(const int _a)
{
const int a = preprocess(_a);
....
}
答案 3 :(得分: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
}
您的示例有一个简单的解决方法:重构。
// 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&
答案 4 :(得分:5)
这可能是一种方法,如果你只是想避免使用其他名称。我建议你在使用它之前再三考虑。
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
}
答案 5 :(得分:4)
我实际上并不建议这样做,但你可以使用创意变量阴影来模拟你想要的东西:
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.
}
}
答案 6 :(得分:0)
答案非常可靠,但是说实话,我真的想不起来要使用这种情况。但是,如果您想预先计算一个常量,这基本上就是您正在做的事情,那么您可以采用几种主要方法你可以做到的。
首先,我们可以执行以下操作。因此,在这种情况下,编译器只需为我们设置CompileA#即可,分别为50、100和150。
const int CompileA1 = EarlyCalc(1);
const int CompileA2 = EarlyCalc(2);
const int CompileA3 = EarlyCalc(3);
int EarlyCalc(int a)
{
a *= 50;
return a;
}
现在,除了此以外,您还有很多方法可以处理此问题。我喜欢别人提到的建议。
void SomeFunc(int a)
{
const int A = EarlyCalc(a);
//We Can't edit A.
}
但是另一种方式可能是...
SomeFunc(EarlcCalc(a));
void SomeFunc(const int A)
{
//We can't edit A.
}
甚至。.
SomeFunction(int a)
{
a *= 50;
ActualFunction(a);
}
void ActualFunction(const int A)
{
//We can't edit A.
}
答案 7 :(得分:-1)
当然,在C ++中使用相同的变量名是无法做到的。