Skip to content

Instantly share code, notes, and snippets.

@santa4nt
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save santa4nt/2e46da2ac0e8a0b30dc4 to your computer and use it in GitHub Desktop.
Save santa4nt/2e46da2ac0e8a0b30dc4 to your computer and use it in GitHub Desktop.
A sample code using specialized, explicit template instantiation of function templates in C++
#include "sample-expl-templ.hpp"
#include <iostream>
typedef uint16_t WORD;
int main()
{
TypeStorage stor;
WORD wValue = 0;
DWORD dwValue = 0;
ULONGLONG ullValue = 0;
// these calls should be dispatched to the specialized explicit instantiation
// of the template method, and NOT to the default implementation for generic types
stor.Get(dwValue); // should be: 42
stor.Get(ullValue); // should be: 4242
// these, however, will be dispatched to compiler-generated instantiation of the
// template method, based on the generic version included in the .hpp header
stor.Set(static_cast<WORD>(4));
stor.Get(wValue);
std::cout << "wValue: " << wValue << std::endl;
std::cout << "dwValue: " << dwValue << std::endl;
std::cout << "ullValue: " << ullValue << std::endl;
return 0;
}
/**
* To run:
* $ g++ -std=c++11 -o sample-expl-templ sample-expl-templ.cpp main.cpp && ./sample-expl-templ
*
* Output:
* wValue: 4
* dwValue: 42
* ullValue: 4242
*/
#include "sample-expl-templ.hpp"
#include <cstring>
TypeStorage::TypeStorage() :
m_dwValue(42),
m_ullValue(4242),
m_upcValue(nullptr),
m_cbValue(0)
{
}
TypeStorage::~TypeStorage()
{
}
bool TypeStorage::Set(const void *blob, size_t size) throw()
{
m_upcValue = std::unique_ptr<char[]>(new char[size]);
std::memcpy(m_upcValue.get(), blob, size);
m_cbValue = size;
return true;
}
bool TypeStorage::Get(void *blob, size_t &size) const throw()
{
if (!m_upcValue || m_cbValue == 0)
{
return false;
}
if (size < m_cbValue)
{
size = m_cbValue;
return false;
}
std::memcpy(blob, m_upcValue.get(), m_cbValue);
return true;
}
// specialized template function instantiations below
template<>
bool TypeStorage::Get<DWORD>(DWORD &value) const throw()
{
value = m_dwValue;
return true;
}
template<>
bool TypeStorage::Set<DWORD>(const DWORD value) throw()
{
m_dwValue = value;
return true;
}
template<>
bool TypeStorage::Get<ULONGLONG>(ULONGLONG &value) const throw()
{
value = m_ullValue;
return true;
}
template<>
bool TypeStorage::Set<ULONGLONG>(const ULONGLONG value) throw()
{
m_ullValue = value;
return true;
}
#ifndef SAMPLE_EXPL_TEMPL_HPP_DEFINED
#define SAMPLE_EXPL_TEMPL_HPP_DEFINED
#include <memory>
#include <cstdint>
#include <assert.h>
typedef uint32_t DWORD;
typedef uint64_t ULONGLONG;
class TypeStorage
{
public:
TypeStorage();
virtual ~TypeStorage();
virtual bool Set(const void *blob, size_t size) throw();
virtual bool Get(void *blob, size_t &size) const throw();
template <typename valuetype>
bool Set(const valuetype value) throw();
template <typename valuetype>
bool Get(valuetype &value) const throw();
private:
DWORD m_dwValue;
ULONGLONG m_ullValue;
std::unique_ptr<char[]> m_upcValue;
size_t m_cbValue;
};
// default template for generic value types that can be dispatched to the
// generic "blob" versions above
template <typename valuetype>
bool TypeStorage::Set(const valuetype value) throw()
{
return Set(&value, sizeof(valuetype));
}
template <typename valuetype>
bool TypeStorage::Get(valuetype &value) const throw()
{
size_t size = sizeof(valuetype);
bool ret = Get(&value, size);
assert (ret);
return ret;
}
#endif//SAMPLE_EXPL_TEMPL_HPP_DEFINED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment