簡體   English   中英

變量類型聲明的C ++模板

[英]C++ template for variable type declaration

我有許多具有不同成員的類,所有這些類都具有以下類型的操作

::basedata::Maindata maindata;
::basedata::Subdata subinfo("This goes into the subinfo vector");
subinfo.contexts(contextInfo);
maindata.subdata().push_back(subinfo);

請注意,我在問如何設置通用模板來執行這些操作。 我無法為每種類型的maindata和subinfo設置特殊情況。 我還需要能夠從主代碼中看到如何調用模板。 如果 maindata.subdata()存在,我已經能夠設置一個模板,但是如果不存在該模板,則在調用該模板時不斷出現編譯失敗。 那就是創建表格的模板

perform_Push(maindata.subdata(), subinfo);

這樣就可以編譯maindata.subdata()是否存在。

我可以接受構建的模板,以便可以顯示主要代碼

bool retval
retval = hasmember(maindata, subdata);
if (retval)
  {
    buildmember(maindata.subdata, subinfo);
    setAttributes(subinfo, data);
    perform_Push(maindata.subdata(), subinfo)
  }
else
  {
    // Perform alternate processing
   }

到目前為止,在調用模板時,if內的代碼將無法編譯。

雖然始終定義:: basedata :: Maindata,但可能會或可能不會定義:: basedata :: Subdata,具體取決於構建我的代碼所使用的庫的版本。 子數據被定義為屬於主數據的向量,因此定義了push_back()操作。 無論如何,子數據類型太多,無法為每種類型的模板中的T :: Subdata創建單獨的模板。

也就是說,如果只有子數據,則可以將模板T的特殊化創建為:: maindata :: subdata和通用模板T。

我對此沒有包含文件或庫的任何控制權,因此我無法創建變量的#define來使用預編譯器進行測試。 有沒有一種好的方法來設置一個模板,使其能夠正常工作? 我可以使用返回布爾值true(成功)或false(沒有此類定義)的模板,並在運行時調用備用處理。 我不需要備用模板。

基本上,我想問的是如何將SFINAE應用於這種特殊情況。

我設法弄清楚了設置基本模板所需做的事情

如果我有最基本的操作

maindata.subdata().push_back(data)

我可以定義表格的模板

<template class T, typename D>
auto doPush(D data) -> decltype(T.pushback(data), void())
{
  T.push_back(data);
}

電話會是

doPush<maindata.subdata()>(data);

但是,問題是當主數據還沒有成員子數據時如何設置它。

您可以使用此模板獲取一個布爾值,該值告訴您是否存在泛型T中的成員類型Subdata 僅當T是結構/類而不是名稱空間時,此方法才有效。

#include <type_traits>

template <class T, class V = void>
  struct hasSubdata
  {
    enum { value = false }; 
  };

template <class T>
  struct hasSubdata<T, typename std::enable_if< std::is_same<typename T::Subdata, typename T::Subdata>::value >::type>
  {
    enum { value = true }; 
  };


struct basedata1
{
  struct Subdata {};
};

struct basedata2
{

};

#include <iostream>

int main ()
{
  std::cout << "basedata1: " << hasSubdata<basedata1>::value << std::endl;
  std::cout << "basedata2: " << hasSubdata<basedata2>::value << std::endl;
}

但是,如果因為編譯器會檢查所有可能性的正確性,則不能使用法線。 您必須以類似的方式行事(非常丑陋):

template <class T, bool = hasSubdata<T>::value>
  struct SubdataUser
  {
    static void foo ()
    {
      std::cout << "I can use SubData member :)" << std::endl;

      typename T::Subdata subinfo ();
    }        
  };

template <class T>
  struct SubdataUser<T, false>
  {
    static void foo ()
    {
      std::cout << "I can not :(" << std::endl;
    }        
  };

int main ()
{
  SubdataUser<basedata1>::foo ();
  return 0;
}

不幸的是,您無法擁有hasMember<Type,Member>::value模板hasMember<Type,Member>::value因為如果Member不存在,則編譯將失敗。

但是您可能想要這種解決方案

#include <type_traits>
#include <iostream>

struct basedata1
{
  struct Subdata1 {};
  struct Subdata2 {};
  struct Subdata3 {};
};

struct basedata2
{
  struct Subdata1 {};
  //struct Subdata2 {};
  struct Subdata3 {};
};

template <class...>
  struct Require
  {
    enum { value = true };
  };

template <class T, bool = true>
  struct Impl
  {
    static void foo ()
    {
      std::cout << "At least one of the members required is not available :(" << std::endl;
    }        
  };

template <class T>
  struct Impl<T, Require< typename T::Subdata1,
                          typename T::Subdata2,
                          typename T::Subdata3 >::value >
  {
    static void foo ()
    {
      std::cout << "All members are available :)" << std::endl;

      typename T::Subdata2 my_var;
    }        
  };


int main( int argc, char* argv[] )
{
  Impl<basedata1>::foo ();
  Impl<basedata2>::foo ();
  return 0;
}

我希望這有幫助

我設法弄清楚了設置基本模板和成員模板所需要做的事情。 它實際上是兩個不同的問題和兩個不同的答案模板。 它需要由特定成員模板調用的基本通用模板。

C ++預處理程序測試是否存在類成員

暫無
暫無

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

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