簡體   English   中英

`std :: enable_if`是函數指針 - 怎么樣?

[英]`std::enable_if` is function pointer - how?

如果用戶將函數指針作為參數傳遞,我想使用SFINAE來啟用特定模板。

我用Google搜索但沒有發現任何內容 - 我也嘗試查看<type_traits>文檔,但找不到類似於is_function_ptr<T>

通過函數指針,我的意思是全局函數指針,如TReturn(*)(TArgs...)

下面是一個類型特征,用於確定某些內容是否為函數指針和幾個測試用例。 注意,為了測試某些東西是否是函數指針,你需要測試std::is_pointer<P>::value是否為true ,如果std::is_function<T>::valuetrue ,其中T是帶指針的P除去。 下面的代碼就是這樣做的:

#include <type_traits>
#include <iostream>
#include <utility>

template <typename Fun>
struct is_fun_ptr
    : std::integral_constant<bool, std::is_pointer<Fun>::value
                            && std::is_function<
                                   typename std::remove_pointer<Fun>::type
                               >::value>
{
};

template <typename Fun>
typename std::enable_if<is_fun_ptr<Fun>::value>::type
test(Fun) {
    std::cout << "is a function pointer\n";
}

template <typename Fun>
typename std::enable_if<!is_fun_ptr<Fun>::value>::type
test(Fun) {
    std::cout << "is not a function pointer\n";
}

void f0() {}
void f1(int) {}
void f2(int, double) {}

struct s0 { void operator()() {} };
struct s1 { void operator()(int) {} };
struct s2 { void operator()(int, double) {} };

int main()
{
    int v0(0);
    int* p0(&v0);
    void (*p1)() = &f0;
    void (**p2)() = &p1;
    std::cout << "v0="; test(v0);
    std::cout << "p0="; test(p0);
    std::cout << "p1="; test(p1);
    std::cout << "p2="; test(p2);

    std::cout << "f0="; test(&f0);
    std::cout << "f1="; test(&f1);
    std::cout << "f2="; test(&f2);

    std::cout << "s0="; test(s0());
    std::cout << "s1="; test(s1());
    std::cout << "s2="; test(s2());

    std::cout << "l0="; test([](){});
    std::cout << "l1="; test([](int){});
    std::cout << "l2="; test([](int, double){});
}

接受函數指針或成員函數指針不需要SFINAE。 為了區分功能對象和不可調用的東西,需要SFINAE,可能沒辦法解決這個問題。

#include <utility>
#include <iostream>

template <typename Ret, typename... Parm>
void moo (Ret (*fp)(Parm...))
{
    std::cout << "funptr" << std::endl;
}

template <typename Ret, typename Owner, typename... Parm>
void moo (Ret (Owner::*fp1)(Parm...))
{
    std::cout << "memfunptr" << std::endl;
}

template <typename Funobj, typename... Parm, 
          typename Ret = 
                   decltype((std::declval<Funobj>())
                            (std::forward(std::declval<Parm>())...))>
void moo (Funobj functor)
{
    std::cout << "funobj" << std::endl;
}

void x1() {}
struct X2 { void x2() {} };
struct X3 { void operator()(){} };


int main()
{
    moo(x1);
    moo(&X2::x2);
    moo(X3());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM