最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++中獲取重載函數(shù)地址的方法

 更新時間:2024年04月02日 09:29:14   作者:流星雨愛編程  
函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數(shù),這 些同名函數(shù)的形參列表不同,常用來處理實現(xiàn)功能類似數(shù)據(jù)類型不同的問題,本文給大家介紹了C/C++中獲取重載函數(shù)地址的方法,需要的朋友可以參考下

1.現(xiàn)象

函數(shù)重載在C/C++編碼中是非常常見的,但是我們在std::bind或std::function綁定函數(shù)地址的時候,直接取地址,程序編譯就會報錯,示例如下:

class CFunc12345
{
public:
	void func12345(int x) {
		std::cout << x;
	}
	void func12345(double x) {
		std::cout << x;
	}
};
 
void func67890(int x) {
	std::cout << x;
}
void func67890(double x) {
	std::cout << x;
}
 
int main()
{
    CFunc12345 x1;
	auto p = std::bind(&CFunc12345::func12345, x1, std::placeholders::_1); //[1]編譯報錯
	p(14124);
 
    auto p1 = std::bind(&func67890, std::placeholders::_1);  //[2]編譯報錯
	p1(33333333);
 
    std::function<void(int)> p2(&func67890);  //[3]編譯報錯
	p2(33333333);
 
    return 0;
}

上述代碼[1],[2],[3]處都會出現(xiàn)編譯錯誤,那是因為函數(shù)重載,多個函數(shù)名相同,找不到該用那個函數(shù)地址。這個時候解決辦法就是人為指定用那個函數(shù),那么人為指定用那個函數(shù)有哪些辦法呢?

2.指定參數(shù)取函數(shù)地址

方法如下:

    //方法1:
    CFunc12345 x1;
	using FUNC1 = void (CFunc12345::*)(int);
	FUNC1 func1 = &CFunc12345::func12345;
	auto p1 = std::bind(func1, x1, std::placeholders::_1);
	p1(14124);
 
	using FUNC2 = void(*)(int);
	FUNC2 func2 = &func67890;
	auto p2 = std::bind(func2, std::placeholders::_1);
	p2(14124);
 
	FUNC2 func3 = &func67890;
	std::function<void(int)> p3(func3);
	p3(14124);

從代碼可以看出,就是手動指定函數(shù)類型,先取到函數(shù)地址后,再把地址傳入指定的對象(如std::bind、std::function等)中,避免了std::bind或std::function去判斷函數(shù)類型,從而避免了編譯錯誤。

3.利用Qt的類QOverload

QOverload是Qt5中提供的一種用于重載信號和槽函數(shù)連接的方式。它允許開發(fā)者在使用信號與槽機制時,更靈活地處理函數(shù)重載的情況。通過將信號和槽函數(shù)的參數(shù)類型轉(zhuǎn)換為指定類型,QOverload實現(xiàn)了對信號和槽函數(shù)的類型安全檢查。

在實際應(yīng)用中,QOverload通過重載調(diào)用QOverload::of,利用它來指定多個信號版本中的具體哪種類型參數(shù)。例如,當(dāng)有一個信號函數(shù)被重載,具有多個不同參數(shù)類型的版本時,可以使用QOverload來明確指定要連接的是哪個版本的信號函數(shù)。

QOverload的作用就是指定重載函數(shù)中的函數(shù)類型,從它的源碼中可以看出來,源碼如下:

template <typename... Args>
struct QNonConstOverload
{
    template <typename R, typename T>
    Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
 
    template <typename R, typename T>
    static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
};
 
template <typename... Args>
struct QConstOverload
{
    template <typename R, typename T>
    Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
 
    template <typename R, typename T>
    static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
};
 
template <typename... Args>
struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
{
    using QConstOverload<Args...>::of;
    using QConstOverload<Args...>::operator();
    using QNonConstOverload<Args...>::of;
    using QNonConstOverload<Args...>::operator();
 
    template <typename R>
    Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
 
    template <typename R>
    static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
};

顧名思義,模版類QNonConstOverload是取不帶const的類成員函數(shù)的地址的,模版類QConstOverload是取帶const的類成員函數(shù)的地址的,QOverload是取普通函數(shù)地址的,它們之間的關(guān)系如下圖所示:

于是上面編譯錯誤的代碼可以修改為:

int main()
{
    //方法2
	CFunc12345 x1;
	auto p = std::bind(QOverload<int>::of(&CFunc12345::func12345), x1, std::placeholders::_1);
	p(14124);
 
	auto p1 = std::bind(QOverload<int>::of(&func67890), std::placeholders::_1);
	p1(33333333);
 
	std::function<void(int)> p2(QOverload<int>::of(&func67890));
	p2(33333333);
 
    return 0;
}

QOverload看似只有裝有Qt環(huán)境才能用,其實把源碼稍加修改就可以作為標(biāo)準(zhǔn)的C++類來用,修改后的COverload源碼如下所示:

template <typename... Args>
struct CNonConstOverload
{
	template <typename R, typename T>
	auto operator()(R(T::* ptr)(Args...)) const -> decltype(ptr)
	{
		return ptr;
	}
 
	template <typename R, typename T>
	static auto of(R(T::* ptr)(Args...)) -> decltype(ptr)
	{
		return ptr;
	}
};
 
template <typename... Args>
struct CConstOverload
{
	template <typename R, typename T>
	auto operator()(R(T::* ptr)(Args...) const) const -> decltype(ptr)
	{
		return ptr;
	}
 
	template <typename R, typename T>
	static auto of(R(T::* ptr)(Args...) const) -> decltype(ptr)
	{
		return ptr;
	}
};
 
template <typename... Args>
struct COverload : CConstOverload<Args...>, CNonConstOverload<Args...>
{
	using CConstOverload<Args...>::of;
	using CConstOverload<Args...>::operator();
	using CNonConstOverload<Args...>::of;
	using CNonConstOverload<Args...>::operator();
 
	template <typename R>
	auto operator()(R(*ptr)(Args...)) const -> decltype(ptr)
	{
		return ptr;
	}
 
	template <typename R>
	static auto of(R(*ptr)(Args...)) -> decltype(ptr)
	{
		return ptr;
	}
};

QOverload在Qt的信號槽中也用的比較多。信號槽連接時,使用基于字符串的語法,可以顯式指定參數(shù)類型。因此,使用重載信號或槽的哪一個實例是明確的。相反,使用基于模版函數(shù)的語法,必須強制轉(zhuǎn)換重載信號或槽,以告訴編譯器要使用哪個實例。

例如,QLCDNumber有三個版本的display() 槽函數(shù):

1.QLCDNumber::display(int)

2.QLCDNumber::display(double)

3.QLCDNumber::display(QString)

使用信號QSlider::valueChanged()和QLCDNumber::display(int)連接,可以有如下系列方法:

     auto slider = new QSlider(this);
     auto lcd = new QLCDNumber(this);
 
     // String-based syntax
     connect(slider, SIGNAL(valueChanged(int)),
             lcd, SLOT(display(int)));
 
     // Functor-based syntax, first alternative
     connect(slider, &QSlider::valueChanged,
             lcd, static_cast<void (QLCDNumber::*)(int)>(&QLCDNumber::display));
 
     // Functor-based syntax, second alternative
     void (QLCDNumber::*mySlot)(int) = &QLCDNumber::display;
     connect(slider, &QSlider::valueChanged,
             lcd, mySlot);
 
     // Functor-based syntax, third alternative
     connect(slider, &QSlider::valueChanged,
             lcd, QOverload<int>::of(&QLCDNumber::display));
 
     // Functor-based syntax, fourth alternative (requires C++14)
     connect(slider, &QSlider::valueChanged,
             lcd, qOverload<int>(&QLCDNumber::display));

總的來說,QOverload是一個強大的工具,它使得在Qt中使用信號和槽機制時,處理函數(shù)重載的情況變得更加簡單和直觀。

以上就是C/C++中重載函數(shù)取地址的方法的詳細內(nèi)容,更多關(guān)于C/C++重載函數(shù)取地址的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言?動態(tài)內(nèi)存管理全面解析

    C語言?動態(tài)內(nèi)存管理全面解析

    動態(tài)內(nèi)存是相對靜態(tài)內(nèi)存而言的。所謂動態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存,本文帶你深入探究C語言中動態(tài)內(nèi)存的管理
    2022-02-02
  • C語言返回值指針的函數(shù)詳解

    C語言返回值指針的函數(shù)詳解

    這篇文章主要為大家詳細介紹了C語言返回值指針的函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • c++實現(xiàn)掃雷小游戲代碼分享

    c++實現(xiàn)掃雷小游戲代碼分享

    這篇文章主要介紹了c++實現(xiàn)掃雷小游戲并附上代碼分享,代碼不能夠?qū)崿F(xiàn)當(dāng)所查坐標(biāo)周圍雷的數(shù)量為0時,直接展開周圍坐標(biāo),但有一點的知識性參考價值,需要的小伙伴可以參考一下
    2022-02-02
  • C語言模擬擲骰子游戲

    C語言模擬擲骰子游戲

    這篇文章介紹了C語言模擬擲骰子游戲的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。需要的朋友可以收藏下
    2021-11-11
  • 最短時間學(xué)會基于C++實現(xiàn)DFS深度優(yōu)先搜索

    最短時間學(xué)會基于C++實現(xiàn)DFS深度優(yōu)先搜索

    常見使用深度優(yōu)先搜索(DFS)以及廣度優(yōu)先搜索(BFS)這兩種搜索,今天我們就來講講什么是深度優(yōu)先搜索,感興趣的可以了解一下
    2021-08-08
  • C++中g(shù)etline()和get()的方法淺析

    C++中g(shù)etline()和get()的方法淺析

    大家都知道作為C++獲取輸入流的方法,幾乎在任何一本資料書上getline()方法和get()方法都作為入門級的方法進行講述,即便如此,筆者在學(xué)習(xí)C++的過程中仍經(jīng)常忘記這二者的使用要點,可能也有C++的初學(xué)者對這兩個方法還心存疑慮,本篇文章就這兩個方法的使用進行簡要闡述。
    2016-10-10
  • C++中std::find函數(shù)介紹和使用場景

    C++中std::find函數(shù)介紹和使用場景

    std::find函數(shù)是一個非常實用的通用查找算法,適用于各種場景,本文主要介紹了C++中std::find函數(shù)介紹和使用場景,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • C語言memset函數(shù)使用方法詳解

    C語言memset函數(shù)使用方法詳解

    這篇文章主要介紹了C語言memset函數(shù)使用方法詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握這樣的方法,需要的朋友可以參考下
    2017-10-10
  • C語言可變參數(shù)與內(nèi)存管理超詳細講解

    C語言可變參數(shù)與內(nèi)存管理超詳細講解

    有時,您可能會碰到這樣的情況,您希望函數(shù)帶有可變數(shù)量的參數(shù),而不是預(yù)定義數(shù)量的參數(shù)。C 語言為這種情況提供了一個解決方案,這篇文章主要介紹了C語言可變參數(shù)與內(nèi)存管理
    2023-01-01
  • C語言實現(xiàn)掃雷游戲詳細代碼實例

    C語言實現(xiàn)掃雷游戲詳細代碼實例

    這篇文章主要介紹了C語言實現(xiàn)掃雷游戲詳細代碼實例,有感興趣的同學(xué)可以借鑒參考下
    2021-02-02

最新評論

上栗县| 长沙市| 黎城县| 烟台市| 桃江县| 临漳县| 包头市| 平遥县| 哈密市| 墨玉县| 城步| 台东市| 柘荣县| 阳江市| 龙游县| 惠水县| 蚌埠市| 邯郸市| 息烽县| 双城市| 武宣县| 松江区| 徐闻县| 壶关县| 兴国县| 军事| 大英县| 布尔津县| 克山县| 文山县| 开远市| 张北县| 马边| 广宁县| 昭平县| 上杭县| 崇仁县| 米林县| 桂平市| 平和县| 中方县|