日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

函数的二义性与函数对象的传递问题(通过实现vector的to_string示例)

發(fā)布時間:2023/12/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数的二义性与函数对象的传递问题(通过实现vector的to_string示例) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

許多時候,我們想要直接打印容器的內(nèi)容,比如

std::vector<int> a = { 1, 2, 3 };

可以打印出[1, 2, 3]。

?

參考標準庫,可以寫出一個帶有迭代器的to_string函數(shù):

template <typename Iter, typename Func> std::string to_string(Iter begin, Iter end, Func func) {std::string str;str.append("[");if (begin != end) {str.append(func(*begin++));while (begin != end) {str.append(", ");str.append(func(*begin++));}}str.append("]");return str; }

在調(diào)用時候,可以直接傳入begin()和end(),作為迭代器,再傳入對于元素的to_string函數(shù),即可實現(xiàn)容器的to_string。

std::to_string是C++11新增的標準庫中定義的函數(shù),具有多個重載函數(shù)(詳情請參考to_string - C++Reference):

string to_string (int val); string to_string (long val); string to_string (long long val); string to_string (unsigned val); string to_string (unsigned long val); string to_string (unsigned long long val); string to_string (float val); string to_string (double val); string to_string (long double val);

由于是重載函數(shù),因此不能直接使用名稱to_string進行函數(shù)的傳遞。

我們想要使用類似于to_string(vec.begin(), vec.end(), to_string)這種傳遞方式,怎么辦呢?

?

在C++11中,我們可以傳遞匿名函數(shù)(lambda)解決二義性問題:

用 [](const T &t) { return to_string(t); } 取代?to_string。

to_string(vec.begin(), vec.end(), [](const T &t) { return to_string(t); });

還有一種方法,就是定義函數(shù)對象:

template <typename T> struct ToString {std::string operator()(const T &t){return to_string(t);} };

to_string(vec.begin(), vec.end(), ToString<T>());

這在C++11標準之前的代碼中經(jīng)常使用。

?

借此,我們可以定義一個vector版的to_string函數(shù):

template <typename T> std::string to_string(const std::vector<T> &vec) {return to_string(vec.begin(), vec.end(),[](const T &t) { return to_string(t); });
} // Or template <typename T> std::string to_string(const std::vector<T> &vec) {return to_string(vec.begin(), vec.end(), ToString<T>()); }

然后,就可以這么使用了:

std::vector<int> a = { 1, 2, 3 };std::vector<int> b = { 4, 5, 6 };std::vector<std::vector<int>> c = { a, b };std::cout << to_string(a) << std::endl; // [1, 2, 3]std::cout << to_string(b) << std::endl; // [4, 5, 6]std::cout << to_string(c) << std::endl; // [[1, 2, 3], [4, 5, 6]]

可以輸出vector的各種類型(包括vector)。

?

然而,存在一個問題就是,由于我的這些代碼在最初就using namespcae std;了,因此并沒有什么問題出現(xiàn)(很好地實現(xiàn)了vector類型的to_string重載)。

但是,當我們把該行去掉后,就會發(fā)現(xiàn),編譯器會報出錯誤。

比如在ToString類的operator()函數(shù)中,在

return to_string(t);

這一行,就報出了:

error: no matching function for call to 'to_string(const int&)'

的錯誤。

似乎解決方法很簡單,直接加std::不就行了嗎?

然而,我們發(fā)現(xiàn),這種解決方法,在只輸出a和b的情況下,確實沒什么問題,但是,當輸出c的時候,又報出了

error: no matching function for call to 'to_string(const std::vector<int>&)'

的錯誤。

——怎么辦呢?

其實解決起來很簡單,就是使用using使得命名空間無效,當然這個using是加在函數(shù)里面的。

template <typename T> struct ToString {std::string operator()(const T &t){using std::to_string; // 標準庫to_stringusing ::to_string; // 自定義to_stringreturn to_string(t);} };

using ::to_string表示你自定義to_string的位置,如果也是在命名空間里面,如(namespace A),那么就寫成using A::to_string;即可。

?

完整代碼如下:

#include <iostream> #include <string> #include <vector>template <typename Iter, typename Func> std::string to_string(Iter begin, Iter end, Func func) {std::string str;str.append("[");if (begin != end) {str.append(func(*begin++));while (begin != end) {str.append(", ");str.append(func(*begin++));}}str.append("]");return str; }template <typename T> struct ToString;template <typename T> std::string to_string(const std::vector<T> &vec) {return to_string(vec.begin(), vec.end(), ToString<T>());// Or/*return to_string(vec.begin(), vec.end(),[](const T &t) {using std::to_string;using ::to_string;return to_string(t);});*/ }template <typename T> struct ToString {std::string operator()(const T &t){using std::to_string;using ::to_string;return to_string(t);} };int main(void) {std::vector<int> a = { 1, 2, 3 };std::vector<int> b = { 4, 5, 6 };std::vector<std::vector<int>> c = { a, b };std::cout << to_string(c) << std::endl;return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/chillmagic/p/5713773.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的函数的二义性与函数对象的传递问题(通过实现vector的to_string示例)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。