const 自动变量的范围

scope of const auto variables

我有一个简单的功能

void simpleFunction(){

const auto img= getImageSomehow();

// do something with img
}

它工作正常。但是我想修改这个函数以在其中包含一个布尔值:

void simpleFunction(bool isGPU){

if(isGPU){
        const auto img= getImagefromGPU();
}
else{
    const auto img= getImageSomehow();
}
// do something with img
}

但这不正确吧?因为 auto 变量的范围 img 没有达到“do something with img”

中的操作

这个也不行

void simpleFunction(bool isGPU){
 const auto img;    
if(isGPU){
        img= getImagefromGPU();
}
else{
    img= getImageSomehow();
}
// do something with img
}

因为声明没有初始化器。

有没有办法以某种方式做到这一点?换句话说,根据 bool 获取 img 然后使用它?

一种选择是将“用 img 做某事”的代码重构到模板中

template<typename ImageType>
void do_something(ImageType const img)  // img is const here as desired
{
  // do something with img
}

然后你原来的函数就变成了

void simpleFunction(bool isGPU)
{
  if(isGPU) 
    do_something(getImagefromGPU());
  else
    do_something(getImageSomehow());
}

范围规则不变。范围保持不变。唯一不同的是类型。

auto关键字看似神奇,其实很简单。 它无法预测未来。这意味着 return 不同类型的分支是不可行的。

因此,您不能先定义一个空的 auto 然后再填充它。您也不能在块内声明 auto 并期望它在该块外可见。

你需要的是避免auto,而是使用可以同时满足这两种情况的单一类型,或者你可以使用继承来弥补差异。然后,您可以使用工厂方法来获取正确类型的“图像 getter”,并对其调用 getImage()

我想在提供解决方案之前突出显示您代码中的错误。

void simpleFunction(bool isGPU) {
  if (isGPU) {
    const auto img = getImagefromGPU();
  }
  else {
    const auto img = getImageSomehow();
  }

  // do something with img
}

在此代码中,img 在 if/else 块的范围内声明,这意味着它在它们之外不可见。鉴于您选择声明 img.

的方式,您根本无法在其范围之外使用 img
void simpleFunction(bool isGPU) {
  const auto img;   
 
  if (isGPU) {
    img = getImagefromGPU();
  }
  else {
    img = getImageSomehow();
  }
  
  // do something with img
}

在这里,虽然您已经解决了作用域问题,但是通过在 if/else 块之外声明变量,您使用 auto 关键字创建了一个问题。 auto 无法解析类型,因为您没有立即声明赋值。结果,您会收到没有初始化程序的错误,因为编译器无法解析适合 img 声明的类型。

考虑到这一点,有一些解决方案。

您可以使用三元运算符,也可以直接声明类型,而不是使用 auto

// ternary

const auto img = isGPU ? getImagefromGPU() : getImageSomehow();

// type declaration

const Image img;

if (isGPU) {
  img = getImagefromGPU();
}
else {
  img = getImageSomehow();
}