c ++模板类型推导:如何将T转换为const T

时间:2017-05-08 22:27:25

标签: c++ templates c++14

我需要根据结构成员的类型使用宏来定义函数。

例如:

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 () {...}

但是这对于非标准的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 {...}

这适用于海湾合作委员会但由于某种原因不适用于CLANG。 CLANG抱怨return-type是零长度数组的数组。为什么呢?

第三次尝试:

所以我的第三次尝试就是这样 - 宣布一个'衰变&#39;功能如下。我有指针类型和非指针类型的单独定义,以便我可以添加 &#34; const&#34;到指针类型

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() { ... } 

但是我看到上面函数的返回类型不是const。

如何使它成为常量?

1 个答案:

答案 0 :(得分:0)

以下作品 -

DECLARE @MinDate DATE = '2017/04/06',
        @MaxDate DATE = '2017/05/09';

SELECT count(*) AS TotalTransactions
    ,sum(Change) AS TransactionsWithChange
    ,(cast(sum(Change) AS FLOAT) / cast(count(*) AS FLOAT)) AS ChangePercent
FROM (
    SELECT TransDetailID
        ,MAX(classChange) AS Change
    FROM (
        SELECT *
            ,LAG(AVClassID, 1, AVClassID) OVER (
                PARTITION BY TransDetailID ORDER BY AVDetailID
                ) AS PrevClassId
            ,CASE 
                WHEN LAG(AVClassID, 1, AVClassID) OVER (
                        PARTITION BY TransDetailID ORDER BY AVDetailID
                        ) != AVClassID
                    THEN 1
                ELSE 0
                END AS ClassChange
        FROM AVTransDetail
        where CreatedDate between @MinDate and @MaxDate
        ) AS CoreData
    GROUP BY TransDetailID
    ) AS ChangeData