2017-05-08 47 views
0

我需要根據結構成員的類型使用宏來定義函數。C++模板類型演繹:如何將T轉換爲常量T

例如:

struct A { 
    uint32_t value; // need to define a function return uint32_t 
    uint8_t str[0]; // need to define a function returning const uint8_t * 
}; 

我需要定義下列功能: -

uint32_t fun() {...} 
const uint8_t *fun() {...} << note the pointer types needs a const 

首先嚐試:

使用std :: decay_t衰減陣列型的指針的被使用作爲退貨類型:std::decay_t<decltype(A::str)> fun() {...}

但這不適用於e如上所述的非標準0長度數組。由於政治原因,我無法改變結構的定義。所以我必須忍受零長度數組。

第二次嘗試: 演繹返回鍵入如下:

template<class T> 
struct decay_zero { using type = std::decay_t<T>; }; 

template<class T> 
struct decay_zero<T[]> { using type = const T *; }; 

template<class T, size_t N> 
struct decay_zero<T[N]> { using type = const T *; }; // adding const to pointer type 

template<class T> 
struct decay_zero<T[0]> { using type = const T *; }; 

template<class T> 
struct return_type { 
private: 
     using U = typename std::remove_reference<T>::type; 
public: 
     using type = decay_zero<U>::type; 
}; 

return_type<decltype(A::str)>::type fun {...} 

這部作品GCC但由於某種原因在CLANG不起作用。 CLANG抱怨return-type是數組長度爲零的數組。爲什麼?

第三次嘗試:

所以我的第三次嘗試是這樣的 - 如下聲明一個「衰退」功能。我有一個指針型和非指針類型單獨定義,這樣我可以添加 「常量」,以指針類型

template < 
      typename T, 
      typename std::enable_if_t<std::is_pointer<T>::value>* = nullptr 
     > 
const T __decayFunction (const T t) // making it const T 
{ 
    return return t; 
} 

template < 
      typename T, 
      typename std::enable_if_t<!std::is_pointer<T>::value>* = nullptr 
     > 
decltype(auto) __decayFunction (T t) 
{ 
    return t; 
} 

template<class T> 
struct return_type { 
private: 
     using U = typename std::remove_reference<T>::type; 
public: 
     using type = decltype(__decayFunction(std::declval<U>())); 
}; 

return_type<decltype(A::str)>::type fun() { ... } 

但我看到的是,以上函數的返回類型不是常量。

如何使它成爲一個常量?

+0

零大小的數組是不允許在C++ –

+0

,但我知道這是一個GCC和CLANG延伸和我住吧 - 因爲這是遺留代碼部分。 – MGH

+0

這是[Clang](http://clang.llvm.org/),而不是CLANG(或CLang)。 –

回答

0

以下作品 -

template <typename T> 
const T *as_const_ptr (const T *p) 
{ 
    return p; 
} 

template < 
      typename T, 
      typename std::enable_if_t<std::is_pointer<T>::value>* = nullptr 
     > 
auto __decayFunction (T t) -> decltype(as_const_ptr(t)) { return as_const_ptr(t); } 

template < 
      typename T, 
      typename std::enable_if_t<!std::is_pointer<T>::value>* = nullptr 
     > 
decltype(auto) __decayFunction (T t) { return t; } 

template<class T> 
struct return_type { 
private: 
     using U = typename std::remove_reference<T>::type; 
public: 
     using type = decltype(__decayFunction(std::declval<U>())); 
}; 
+0

但它爲什麼工作? –

+0

我不確定。因此我沒有接受答案:-)我正在等模板專家解釋。當作爲函數參數傳遞時,T被推導爲指針類型。所以w/char a [10],T將會是char *,添加一個const以某種方式被忽略。函數簽名爲T * 'template const T * __decayFunction(const T * t){return t; }' – MGH

相關問題