有沒有辦法在 C 中定義一個函式,以便我可以做這樣的事情:
foo( "Error on line " << iLineNumber );
foo( "name " << strName << " is Invalid" );
就像現在一樣,我必須在呼叫 foo 函式之前宣告一個 ostringstream 物件,如下所示:
std::ostringstream strStream1;
ostringstream1 << "Error on line " << iLineNumber;
foo( ostringstream1 );
std::ostringstream strStream2;
ostringstream2 << "name " << strName << " is Invalid";
foo( ostringstream2 );
uj5u.com熱心網友回復:
編譯器無法推斷出您希望將運算式轉換為std::ostringstream. 您可以通過顯式為引數提供一個來解決此問題,您可以與函式行內:
#include <sstream>
#include <string>
void foo(std::ostringstream osstr)
{
// Use the stream
}
int main()
{
const int iLineNumber = 10;
const std::string strName = "file.cpp";
foo( std::ostringstream{} << "Error on line " << iLineNumber );
foo( std::ostringstream{} << "name " << strName << " is Invalid" );
}
但是,我建議使用引數包和折疊運算式來轉發引數:
#include <sstream>
#include <string>
#include <utility>
// Parameter, variable number of arguments of various types
template<class ... T>
void foo(T&& ... args)
{
std::ostringstream stream;
// Fold expression, for each argument in args, add it to the stream
(stream << ... << std::forward<T>(args));
// Use the stream
}
int main()
{
const int iLineNumber = 10;
const std::string strName = "file.cpp";
foo( "Error on line ", iLineNumber );
foo( "name ", strName, " is Invalid" );
}
uj5u.com熱心網友回復:
直接的問題是下面的字串和數字
oss << "String " << number;
不是“ost??ringstream 引數”。它們都是該std::ostream& operator<< (std::ostream&, T)族不同多載的引數。整個陳述句擴展為
operator<<(operator<<(oss, "String "), number);
并且令牌"String " << number永遠不會被評估為運算式。沒有合適的多載operator<<,即使有,也沒有理由期望它會創建ostringstream你想要的。
大致有三種方法可以做你想做的事,弗朗索瓦已經展示了兩種:
手動創建匿名
ostringstream不漂亮,現在沒有額外的作業,但每個呼叫站點都有額外的作業
使您的函式成為可變引數模板(或撰寫可變引數包裝器)以將引數格式化為
ostringstream適合您的易于實作,但不使用
<<您似乎如此熱衷的語法撰寫一個流代理哨兵型別,在呼叫站點看起來像這樣:
foo() << "Error on line " << iLineNumber;這只是為了保留句法風格而付出的努力,但有時可能是合理的。
該物件將包含一個
ostringstream并有一個模板operator<<,允許它格式化任何型別。我稱它為“哨兵”,因為它還需要
foo()使用該格式化字串從其解構式中呼叫原始函式。foo()如果內部函式可能會拋出,這實際上是一個非常糟糕的主意。
uj5u.com熱心網友回復:
@Useless 提供了一些可能性。我會再加入一個,看看你是否覺得它有趣。
現在,您的有效代碼類似于:
std::ostringstream buffer;
buffer << "whatever";
foo(buffer);
可以很容易地扭轉這種局面,可以這么說,沿著這些思路得到一些東西:
std::ostringstream buffer;
buffer << "whatever" << exec(foo);
...并使用字串流的當前內容進行exec呼叫:foo
class exec {
void (*func)(std::string const &);
public:
exec(void (*func)(std::string const &)) : func(func) {}
friend std::ostream &operator<<(std::ostream &os, exec const &e) {
std::ostringstream &oss = dynamic_cast<std::ostringstream &>(os);
e.func(oss.str());
return os;
}
};
這是一個簡單(但完整)的作業示例:
#include <string>
#include <sstream>
#include <iostream>
class exec {
void (*func)(std::string const &);
public:
exec(void (*func)(std::string const &)) : func(func) {}
friend std::ostream &operator<<(std::ostream &os, exec const &e) {
std::ostringstream &oss = dynamic_cast<std::ostringstream &>(os);
e.func(oss.str());
return os;
}
};
void foo(std::string const &s) {
std::cout << s;
}
int main() {
std::ostringstream os;
os << "This is some stuff: " << 1 << " " << 3.14 << exec(foo);
}
...這幾乎產生了您所期望的:
This is some stuff: 1 3.14
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/530016.html
標籤:C 细绳功能溪流论据
上一篇:一個字串的所有子串,沒有改組
