简单演示通过模板元编程计算容器大小

2018-06-17 20:50:01来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

源代码:

#ifndef UTILITY_H
#define UTILITY_H

#include <type_traits>


namespace utility
{

template <typename ...Args>
struct type_size_sum
{
    static constexpr size_t size_sum = 0;            // for empty parameter
};

template <typename T>
struct type_size_sum<T>
{
    static constexpr size_t size_sum = sizeof(T);
};

template <typename T, typename ...Args>
struct type_size_sum<T, Args...>
{
    static constexpr size_t size_sum = sizeof(T) + type_size_sum<Args...>::size_sum;
};

}

template <size_t buf_size>
class ProtocolBuf
{
public:
    static_assert(sizeof(unsigned char) == 1, "unsigned char should be sizeof(1) to ensure the implementation is correct");
public:
    ProtocolBuf() 
    {
    }

    template <typename T>
    ProtocolBuf& operator<<(T&& t)
    {
        static_assert(std::is_trivially_copyable<std::remove_reference<T>>::value, "trivially copyable from unconscious errors");
        static_assert(std::is_trivially_destructible<T>::value, "trivially destructible from unconscious errors");
        static_assert(!std::is_pointer<T>::value, "using pointer may be errors");

        std::copy((unsigned char*)&t, (unsigned char*)&t + sizeof(T), m_buf + m_curPos);
        m_curPos += sizeof(T);
        return *this;
    }

    void setValid() { m_curPos = 0; }

    template <typename T>
    ProtocolBuf& operator>>(T&& t)
    {
        static_assert(std::is_trivially_copyable<std::remove_reference_t<T>>::value, "trivially copyable from unconscious errors");
        static_assert(std::is_trivially_destructible<T>::value, "trivially destructible from unconscious errors");
        static_assert(!std::is_pointer<T>::value, "using pointer may be errors");

        std::copy(m_buf + m_curPos, m_buf + m_curPos + sizeof(T), (unsigned char*)&t);
        m_curPos += sizeof(T);
        return *this;
    }

private:
    unsigned char m_buf[buf_size];
    size_t m_curPos = 0;
};

template <size_t buf_size, typename... Args>
inline void insertToBuf(ProtocolBuf<buf_size>& buf, Args&&... args);

template <size_t buf_size, typename T>
inline void insertToBuf(ProtocolBuf<buf_size>& buf, T&& t)
{
    buf << t;
}

template <size_t buf_size, typename T, typename ...Args>
inline void insertToBuf(ProtocolBuf<buf_size>& buf, T&& t, Args&& ...args)
{
    buf << t;
    insertToBuf(buf, std::forward<Args>(args)...);
}

template <typename... Args>
auto make_protocolBuf(Args&&... args)
{
    constexpr size_t buf_size = utility::type_size_sum<Args...>::size_sum;

    ProtocolBuf<buf_size> buf;

    insertToBuf(buf, std::forward<Args>(args)...);

    buf.setValid();

    return buf;
}

#endif    // UTILITY_H

实现代码:

#include <iostream>
#include "Utility.h"


int main()
{
    auto buf = make_protocolBuf(11, 34, 25);

    int i1, i2, i3;
     buf >> i1 >> i2 >> i3;

    std::cout << "i1: " << i1 << std::endl;
    std::cout << "i2: " << i2 << std::endl;
    std::cout << "i3: " << i3 << std::endl;

    return 0;
}

上面只是自己随便写的关于模板元编程的简单例子,可以用在希望在堆栈上创建数组的情况下,用来简化使用。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:28.C++- 单例类模板(详解)

下一篇:VC6.0 突然打不开dsw 工程文件的解决方案