我需要根据结构成员的类型使用宏来定义函数。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() { ... }
但我看到的是,以上函数的返回类型不是常量。
如何使它成为一个常量?
零大小的数组是不允许在C++ –
,但我知道这是一个GCC和CLANG延伸和我住吧 - 因为这是遗留代码部分。 – MGH
这是[Clang](http://clang.llvm.org/),而不是CLANG(或CLang)。 –