第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

是否可以編寫模板來檢查函數(shù)的存在?

是否可以編寫模板來檢查函數(shù)的存在?

天涯盡頭無女友 2019-05-24 15:12:24
是否可以編寫模板來檢查函數(shù)的存在?是否可以編寫一個(gè)模板來改變行為,具體取決于是否在類上定義了某個(gè)成員函數(shù)?這是我想寫的一個(gè)簡單例子:template<class T>std::string optionalToString(T* obj){     if (FUNCTION_EXISTS(T->toString))         return obj->toString();     else         return "toString not defined";}所以,如果class T已經(jīng)toString()確定的話,就使用它; 否則,它沒有。我不知道怎么做的神奇部分是“FUNCTION_EXISTS”部分。
查看完整描述

5 回答

?
Smart貓小萌

TA貢獻(xiàn)1911條經(jīng)驗(yàn) 獲得超7個(gè)贊

是的,使用SFINAE,您可以檢查給定的類是否提供某種方法。這是工作代碼:

#include <iostream>struct Hello{
    int helloworld() { return 0; }};struct Generic {};    // SFINAE testtemplate <typename T>class has_helloworld{
    typedef char one;
    typedef long two;

    template <typename C> static one test( typeof(&C::helloworld) ) ;
    template <typename C> static two test(...);    public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };};int main(int argc, char *argv[]){
    std::cout << has_helloworld<Hello>::value << std::endl;
    std::cout << has_helloworld<Generic>::value << std::endl;
    return 0;}

我剛用Linux和gcc 4.1 / 4.3測試過它。我不知道它是否可以移植到運(yùn)行不同編譯器的其他平臺


查看完整回答
反對 回復(fù) 2019-05-24
?
UYOU

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個(gè)贊

這個(gè)問題很老,但是使用C ++ 11,我們有了一種新方法來檢查函數(shù)是否存在(或者確實(shí)存在任何非類型成員),再次依賴SFINAE:

template<class T>auto serialize_imp(std::ostream& os, T const& obj, int)
    -> decltype(os << obj, void()){
  os << obj;}template<class T>auto serialize_imp(std::ostream& os, T const& obj, long)
    -> decltype(obj.stream(os), void()){
  obj.stream(os);}template<class T>auto serialize(std::ostream& os, T const& obj)
    -> decltype(serialize_imp(os, obj, 0), void()){
  serialize_imp(os, obj, 0);}

現(xiàn)在進(jìn)行一些解釋。首先,如果內(nèi)部的第一個(gè)表達(dá)式無效(也就是說,函數(shù)不存在),我使用表達(dá)式SFINAEserialize(_imp)從重載解析中排除函數(shù)decltype。

void()是用來做的所有這些函數(shù)的返回類型void。

如果兩者都可用,則該0參數(shù)用于優(yōu)先選擇重載os << obj(文字0是類型的int,因此第一個(gè)重載是更好的匹配)。


現(xiàn)在,您可能需要一個(gè)特征來檢查函數(shù)是否存在。幸運(yùn)的是,寫起來很容易。但是請注意,您需要為自己想要的每個(gè)不同的函數(shù)名自己編寫一個(gè)特征。

#include <type_traits>template<class>struct sfinae_true : std::true_type{};namespace detail{
  template<class T, class A0>
  static auto test_stream(int)
      -> sfinae_true<decltype(std::declval<T>().stream(std::declval<A0>()))>;
  template<class, class A0>
  static auto test_stream(long) -> std::false_type;} // detail::template<class T, class Arg>struct has_stream :
   decltype(detail::test_stream<T, Arg>(0)){};

實(shí)例。

并解釋。首先,sfinae_true是一個(gè)幫助器類型,它基本上與寫入相同decltype(void(std::declval<T>().stream(a0)), std::true_type{})。優(yōu)點(diǎn)是它更短。
接下來,取決于簽入是否失敗,struct has_stream : decltype(...)從任一端std::true_typestd::false_type最后繼承。 最后,為您提供所傳遞的任何類型的“值”,而無需您知道如何構(gòu)建它。請注意,這只能在未評估的上下文中使用,例如,和其他。decltypetest_stream
std::declvaldecltypesizeof


請注意,decltype不一定需要,因?yàn)?code>sizeof(并且所有未評估的上下文)都獲得了增強(qiáng)。它只是decltype已經(jīng)提供了一種類型,因此只是更清潔。這是一個(gè)sizeof重載的版本:

template<class T>void serialize_imp(std::ostream& os, T const& obj, int,
    int(*)[sizeof((os << obj),0)] = 0){
  os << obj;}

由于同樣的原因,intlong參數(shù)仍然存在。數(shù)組指針用于提供sizeof可以使用的上下文。


查看完整回答
反對 回復(fù) 2019-05-24
?
守著星空守著你

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超8個(gè)贊

雖然這個(gè)問題已經(jīng)有兩年了,但我還是敢補(bǔ)充一下。希望它能澄清以前無可爭議的優(yōu)秀解決方案。我采用了Nicola Bonelli和Johannes Schaub的非常有用的答案,并將它們合并為一個(gè)解決方案,即恕我直言,更易讀,更清晰,不需要typeof擴(kuò)展:

template <class Type>class TypeHasToString{
    // This type won't compile if the second template parameter isn't of type T,
    // so I can put a function pointer type in the first parameter and the function
    // itself in the second thus checking that the function has a specific signature.
    template <typename T, T> struct TypeCheck;

    typedef char Yes;
    typedef long No;

    // A helper struct to hold the declaration of the function pointer.
    // Change it if the function signature changes.
    template <typename T> struct ToString
    {
        typedef void (T::*fptr)();
    };

    template <typename T> static Yes HasToString(TypeCheck< typename ToString<T>::fptr, &T::toString >*);
    template <typename T> static No  HasToString(...);public:
    static bool const value = (sizeof(HasToString<Type>(0)) == sizeof(Yes));};

我用gcc 4.1.2檢查了它。這個(gè)功勞主要?dú)w功于Nicola Bonelli和Johannes Schaub,如果我的回答可以幫助你,請給他們一個(gè)投票:)


查看完整回答
反對 回復(fù) 2019-05-24
  • 5 回答
  • 0 關(guān)注
  • 691 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號