亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Std:Enable_if可以有條件地編譯成員函數

Std:Enable_if可以有條件地編譯成員函數

C++
LEATH 2019-07-03 15:30:22
Std:Enable_if可以有條件地編譯成員函數我試著用一個簡單的例子來理解如何使用std::enable_if..在我讀完之后這個答案我認為想出一個簡單的例子應該不難。我想用std::enable_if在兩個成員函數之間進行選擇,并且只允許其中一個被使用。不幸的是,下面的代碼沒有用GCC 4.7編譯,經過幾個小時的嘗試,我問你們我的錯誤是什么。#include <utility>#include <iostream>template< class T >class Y {     public:         template < typename = typename std::enable_if< true >::type >         T foo() {             return 10;         }         template < typename = typename std::enable_if< false >::type >         T foo() {             return 10;         }};int main() {     Y< double > y;     std::cout << y.foo() << std::endl;}GCC報告了以下問題:% LANG=C make CXXFLAGS="-std=c++0x" enable_if g++ -std=c++0x    enable_if.cpp   -o enable_if enable_if.cpp:12:65: error: `type' in `struct std::enable_if<false>' does not name a type enable_if.cpp:13:15: error: `template<class T> template<class> T Y::foo()' cannot be overloaded enable_if.cpp:9:15: error: with `template<class T> template<class> T Y::foo()'為什么g+不刪除第二個成員函數的錯誤實例化?根據標準,std::enable_if< bool, T = void >::type只有當布爾模板參數為真時才存在。但是為什么g+不認為這是SFINAE呢?我認為重載錯誤消息來自g+不刪除第二個成員函數的問題,并認為這應該是過載
查看完整描述

3 回答

?
嗶嗶one

TA貢獻1854條經驗 獲得超8個贊

SFINAE只有當替換在參數演繹中的模板參數使構造不正確時才有效。沒有這樣的替代。

我也是這么想的,我試著用std::is_same< T, int >::value! std::is_same< T, int >::value結果是一樣的。

這是因為當類模板被實例化時(當您創建一個類型為Y<int>在其他情況下),它實例化其所有成員聲明(不一定是它們的定義/主體!)。其中還包括其成員模板。請注意T就知道了,而且!std::is_same< T, int >::value結果是假的。所以它將創建一個類Y<int>其中包含

class Y<int> {
    public:
        /* instantiated from
        template < typename = typename std::enable_if< 
          std::is_same< T, int >::value >::type >
        T foo() {
            return 10;
        }
        */

        template < typename = typename std::enable_if< true >::type >
        int foo();

        /* instantiated from

        template < typename = typename std::enable_if< 
          ! std::is_same< T, int >::value >::type >
        T foo() {
            return 10;
        }
        */

        template < typename = typename std::enable_if< false >::type >
        int foo();};

這個std::enable_if<false>::type訪問不存在的類型,因此聲明格式不正確。因此你的程序是無效的。

您需要使成員模板‘enable_if依賴于成員模板本身的參數。那么聲明是有效的,因為整個類型仍然是依賴的。當您試圖調用其中之一時,它們的模板參數的參數推導就會發生,而SFINAE就會像預期的那樣發生。看見這個問題以及如何做到這一點的相應答案。


查看完整回答
反對 回復 2019-07-03
?
DIEA

TA貢獻1820條經驗 獲得超3個贊

我做了這個簡短的例子,這也是有效的。

#include <iostream>#include <type_traits>class foo;class bar;template<class T>struct is_bar{
    template<class Q = T>
    typename std::enable_if<std::is_same<Q, bar>::value, bool>::type check()
    {
        return true;
    }

    template<class Q = T>
    typename std::enable_if<!std::is_same<Q, bar>::value, bool>::type check()
    {
        return false;
    }};int main(){
    is_bar<foo> foo_is_bar;
    is_bar<bar> bar_is_bar;
    if (!foo_is_bar.check() && bar_is_bar.check())
        std::cout << "It works!" << std::endl;

    return 0;}

如果你想讓我詳細解釋的話。我認為這段代碼或多或少是不言自明的,但我還是這樣做了,所以我可能錯了:)

你可以看到它的作用這里.


查看完整回答
反對 回復 2019-07-03
?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

對于那些正在尋找“只起作用”的解決方案的后來者來說:

#include <utility>#include <iostream>template< typename T >class Y {

    template< bool cond, typename U >
    using resolvedType  = typename std::enable_if< cond, U >::type; 

    public:
        template< typename U = T > 
        resolvedType< true, U > foo() {
            return 11;
        }
        template< typename U = T >
        resolvedType< false, U > foo() {
            return 12;
        }};int main() {
    Y< double > y;

    std::cout << y.foo() << std::endl;}

匯編:

g++ -std=gnu++14 test.cpp

跑步給:

./a.out 
11


查看完整回答
反對 回復 2019-07-03
  • 3 回答
  • 0 關注
  • 1918 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號