将setw()作为变量放置

Place setw() as a variable

本文关键字:变量 setw      更新时间:2023-10-16

我有一个示例代码块:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(){
string blank = " ";
cout << "Hello" << blank << "47"; 
}

我的原始代码中有很多这种类型的cout。我希望能够将blank字符串更改为setw(2)函数,而不必在我的代码中的每个cout上用setw(1)替换blank。那么,有没有一种方法可以将cpp函数设置为变量呢?所以我可以通过键入名称来调用函数?例如:

func blank = setw(2);
cout<< "Hello" << blank << "47";

std::setw(x)的类型未指定,但您不需要知道。

您只需使用auto:

auto blank = std::setw(2);

正如@StoryTeller所指出的,虽然这应该在正常的实现中工作,但不能保证。

一个更安全的选择是创建一个具有过载<<:的类

struct blank_t {} blank;
std::ostream &operator<<(std::ostream &s, blank_t)
{
return s << std::setw(2);
}

std::setw是一个操纵器。它的类型是未指定的,并且是特定于实现的。

那么有没有办法将cpp函数设置为变量?

使用C++11,您可以使用函数对象,尤其是std::function。还有lambda表达式。

我不确定你是否想在你的情况下使用它。

所以要学会使用源代码编辑器。将每次出现的blank替换为适当的内容,即std::setw(2)。。。。这使您的代码可读性更强。好的编辑很容易做到这一点。

你可以滥用预处理器,并有

#define blank setw(2)

但在您的情况下,这是一个坏主意(因为代码仍然不可读)。即使使用HolyBlackCat所回答的auto,也会使您的代码变得不可读和混乱。

代码的阅读频率远高于编写频率。保持它的可读性(即使是你自己,几周后)。

如果你有一个巨大的(百万行)项目,在这种情况下,花几分钟时间写一些脚本来更改你的源代码。顺便说一句,使用GNU emacs很容易(因为emacs是一个可脚本化的编辑器)。

另一种解决方案是编写一个小包装类,其唯一目的是为封装的引用对象提供重载的operator<<。您可以对该类进行模板化,使其能够首先与您可以提供给std::ostream的所有内容一起工作。

这里有一个例子:

#include <iostream>
#include <iomanip>
#include <string>
template <class T>
struct Blank {
Blank(T const& t) : t(t) {}
T const& t;
};
// utility function so that you can use type deduction at the call site:
template <class T>
Blank<T> blank(T const& t) {
return Blank<T>(t);
}
template <class T>
std::ostream& operator<<(std::ostream& os, Blank<T> const& blank) {
os << std::setw(2) << blank.t;
return os;
}
int main() {
std::cout << "Hello" << blank("4") << blank(7) << blank(std::string("8")) << 'n';
}

这并不是你所要求的语法,但它非常接近。

您还必须确保在operator<<中使用封装的对象之前,没有任何封装的对象被销毁(因为这样会由于悬挂引用而导致未定义的行为),但如果从不创建命名的Blank对象,则很容易实现。