问题描述
考虑以下头文件:
// Foo.h
class Foo {
public:
template <typename T>
void read(T& value);
};
我要明确地实例化在所有类型的源文件的Foo ::阅读
成员函数模板包含在的boost :: MPL: :矢量
:
// Foo.cc
#include <boost/mpl/vector.hpp>
#include <boost/mpl/begin_end.hpp>
#include "Foo.h"
template <typename T>
void Foo::read(T& value) { /* do something */ }
typedef boost::mpl::vector<int, long, float> types;
// template Foo::read<int >(int&);
// template Foo::read<long >(long&);
// template Foo::read<float>(float&);
// instantiate automatically ???
这可能吗?在此先感谢,丹尼尔。
Is it possible? Thanks in advance, Daniel.
修改
我找到了一些解决方案 - 它似乎分配一个指针富::阅读&LT; T&GT;
在一个结构的构造,它的变量随后宣布,因实例:
I found some solution - it seems that assigning a pointer to Foo::read<T>
in the constructor of a struct, of which variable is then declared, cause instantiation:
// intermezzo
template <typename T> struct Bar {
Bar<T>() {
void (Foo::*funPtr)(T&) = &Foo::read<T>;
}
};
static Bar<int > bar1;
static Bar<long > bar2;
static Bar<float> bar3;
于是该过程可以automatized如下:
So then the process can be automatized as follows:
// Foo.cc continued
template <typename B, typename E>
struct my_for_each {
my_for_each<B, E>() {
typedef typename B::type T; // vector member
typedef void (Foo::*FunPtr)(T&); // pointer to Foo member function
FunPtr funPtr = &Foo::read<T>; // cause instantiation?
}
my_for_each<typename boost::mpl::next<B>::type, E> next;
};
template<typename E>
struct my_for_each<E, E> {};
static my_for_each< boost::mpl::begin<types>::type,
boost::mpl::end<types>::type > first;
但我不知道,如果这个解决方案是便携式和符合标准的? (与英特尔和GNU编译器。)
But I don't know if this solution is portable and standard-conformant? (Works with Intel and GNU compilers.)
推荐答案
如果你打算使用你的类只在单个模块(即你不会导出),可以使用升压/ MPL /的for_each。这种方式定义(使用MPL /的for_each)模板功能不会被导出(即使你申报类名或函数签名之前__declspec(出口)):
If you intend to use your class only in a single module (i.e. you won't export it) you can use boost/mpl/for_each. The template function defined this way (using mpl/for_each) won't be exported (even if you declare __declspec(export) before class name or function signature):
// Foo.cpp
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
template<class T>
void read(T& value)
{
...
}
using types = boost::mpl::vector<long, int>;
//template instantiation
struct call_read {
template <class T>
void operator()(T)
{
T t; //You should make sure that T can be created this way
((Foo*)nullptr)->read<T>(t); //this line tells to compiler with templates it should instantiate
}
};
void instantiate()
{
boost::mpl::for_each<types>(call_read());
}
如果你需要导出/导入您结构和模板方法存在使用升压/ preprocessor解决方案
If you need export/import you structure and template methods there is the solution using boost/preprocessor
// Foo.h
#ifdef <preprocessor definition specific to DLL>
# define API __declspec(dllexport)
#else
# define API __declspec(dllimport)
#endif
class API Foo {
public:
template<class T> void read(T& value);
};
// Foo.cpp
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/mpl/vector.hpp>
template<class T>
void read(T& value)
{
...
}
//using this macro you can define both boost::mpl structure AND instantiate explicitly your template function
#define VARIANT_LIST (std::wstring)(long)(int)
using types = boost::mpl::vector<BOOST_PP_SEQ_ENUM(VARIANT_LIST)>;
//Here we should use our API macro
#define EXPLICIT_INSTANTIATION(r, d, __type__) \
template API void Foo::read<__type__>(__type__&);
BOOST_PP_SEQ_FOR_EACH(EXPLICIT_INSTANTIATION, _, VARIANT_LIST)
如果您不需要这个额外的功能的第一个解决方案是干净多了我觉得
If you don't need this extra functionality the first solution is much cleaner I guess
这篇关于如何明确实例在C ++ MPL向量的所有成员的模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!