【问题标题】:Wrapping std::cout in a function call在函数调用中包装 std::cout
【发布时间】:2012-07-16 20:35:55
【问题描述】:

我有很多 couts,所以我希望能够创建一个只接受三个参数的函数。该函数会将它们打印到屏幕上,就像 cout 一样:

print( 5, " is a ", "number" );

// should do the same thing as

cout << 5 << " is a " << "number" << endl;

我没有要求任何人这样做。我只是在寻找一种能够做到的方法。但如果你能提供代码也很好。有人有建议吗?谢谢。

【问题讨论】:

  • 1) 你尝试过什么,2) 功能比cout &lt;&lt; ... 更好,3) 你听说过模板吗?

标签: c++


【解决方案1】:
template <typename T0, typename T1, typename T2>
void print(T0 const& t0, T1 const& t1, T2 const& t2)
{
    std::cout << t0 << t1 << t2 << std::endl;
}

【讨论】:

  • Scott Meyers(在 Effective C++ 中)建议您对所有类型使用 pass by const ref,除了内置类型(char、int、double 等)、迭代器和函数对象(类派生自 std::*_function)。
  • const&amp; t0 有什么作用?请用外行的方式解释,因为我不太精通 C++。
  • @0A0D:确实如此,鉴于原始问题中的具体示例,人们可能更喜欢按值传递(也可能更喜欢不使用模板,具体取决于论据是)。但是,在模板中,规范是通过 const&amp; 而不是按值接受,以处理“最坏情况”。
  • @David:这是一个 const 限定参考。更多信息,我会推荐a good introductory C++ text
  • @0A0D:在我的脑海中,我想不出一个“官方”参考。请参阅 this question 了解为什么 const&amp;(或 C++11 中的 &amp;&amp;)通常更可取的几个原因。
【解决方案2】:

我希望能够制作一个只接受三个参数的函数

你确定吗? C++11 为我们提供的功能远不止于此。

void print()
{
    std::cout << std::endl;
}

template<typename T, typename... Args>
void print(const T & val, Args&&... args)
{
    std::cout << val;
    print(args...);
}

【讨论】:

  • 我说我只想要三个参数,因为我担心给我的描述可以接受无限参数的函数的例子太复杂了,我无法掌握。这段代码应该按原样工作吗?我运行了它,它给了我错误:expected ',' or '...' before '&amp;&amp;' token'
  • @David:你用的是什么编译器?
  • 我正在使用 CodeBlocks 的内置编译器。
  • 我忘了说我收到了一条警告,上面写着variadic templates only available with -std=c++0x or -std=gnu++0x我不知道这是什么意思。
  • @David:那可能是 GCC,虽然我不知道是哪个版本。如果您能弄清楚如何将选项 "-std=c++0x" 添加到命令行,那么就这样做。如果您不知道我在说什么,请访问代码块论坛here,看看他们是否可以帮助您。问他们,“我如何设置代码块以使用 C++11?”,他们应该能够帮助你。 (编辑)根据您的其他评论,我看到您肯定有一个支持该选项的 GCC 版本。你只需要弄清楚如何添加它。
【解决方案3】:

你可以用模板做到这一点:

template<typename T, typename S, typename U>
print(T x, S y, U z)
{
    std::cout << x << y << z;
}

编辑:如果您希望传递复杂类型(不仅仅是 intchar *),您应该遵循 James 的回答并使用 const 引用。

【讨论】:

    【解决方案4】:

    您可以使用宏...(如果您想这样做,有时会很丑)

    #define PRINT(x,y,z) cout << (x) << (y) << (z) << endl;
    

    【讨论】:

    • 我喜欢您的回答,因为您不必使用模板。 :)
    • 在我看来,这更多的是可读性优势。此外,您可以将各种类型传递给print
    • 如果你必须经常写,使用宏比模板方便得多。
    • 有什么比较方便的?
    • @Misch:或者,通过模板类型推导,print("a","b",3) vs. print("a","b",3)
    【解决方案5】:

    如果您希望简化打印三个项目的特定任务,您可以使用#define 宏来完成:

    #define print(A,B,C) cout << (A) << (B) << (C) << endl
    

    如果您更喜欢函数调用语法,请考虑使用 C 风格的输出:printf 是 C++ 标准库的“一流成员”,当它有意义时没有理由回避它在您的特定应用程序中:

    printf("%d %s %s\n", 5, "is a", "number");
    

    printf 方法的优点是它不限于任何特定数量的参数。

    【讨论】:

    • print(a++, "is a", a++); 比未指定更糟糕,它是未定义的,即使 print 是一个函数而不是宏也是如此。但这不是函数/宏的错,而是调用者的错。
    • @BenjaminLindley 你是对的,就这个问题而言,参考是没有意义的。我编辑了答案以将其删除,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    相关资源
    最近更新 更多