将setw()作为变量

时间:2017-11-12 15:38:24

标签: c++

我有这个示例代码块:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

int main(){
    string blank = " ";
    cout << "Hello" << blank << "47"; 
}

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

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

3 个答案:

答案 0 :(得分:10)

std::setw(x)的类型为unspecified,但您无需了解它。

您可以使用auto

auto blank = std::setw(2);

正如@StoryTeller指出的那样,虽然应该在理智的实现上工作,但不能保证。

更安全的选择是创建一个重载<<的类:

struct blank_t {} blank;

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

答案 1 :(得分:3)

std::setw是一个操纵者。其类型未指定且具体实现。

  

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

使用C ++ 11,您可以使用function objects,尤其是std::function。你也有lambda expressions

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

因此,请学习使用source code editor。将每个.section { width: 200px; height: 40px; background-color: green; margin: 10px; }替换为适当的内容,即<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>How many products would you like listed per page?</p> <select id="choice"> <option value="0"></option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> <div id="results"> <div class="section">This is a regular div</div> <div class="section">This is a regular div</div> <div class="section">This is a regular div</div> <div class="section">This is a regular div</div> <div class="section">This is a regular div</div> </div> ....这样可以使代码更具可读性。优秀的编辑能够轻松完成。

您可以滥用preprocessor,然后

blank

但在你的情况下,这是一个坏主意(因为代码仍然不可读)。即使使用std::setw(2)作为answered by HolyBlackCat,您的代码仍然难以置信且令人困惑。

代码比阅读更经常阅读。保持可读性(即使是在几周内自己完成)。

如果你有一个巨大的(百万行)项目,花费几分钟时间写一些脚本来改变你的源代码。顺便说一句,使用GNU emacs很简单(因为#define blank setw(2) 可编写脚本的编辑器)。

答案 2 :(得分:1)

另一种解决方案是编写一个小包装类,其唯一目的是为封装的引用对象提供重载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<<中使用之前没有销毁任何封装对象(因为由于悬空引用你会有未定义的行为),但是如果永远不创建名为{那么这很容易实现{1}}对象。