我写这封信旨在拍摄随机三维向量类,但我用几个几何库在我的项目(一个包含在三维仿真,一个纳入分析框架,其中一个是没有包含在1 GB以上的框架中......)。每个图书馆都有自己的向量的定义,与同样的方法不同的名称,例如具有的getX()的getX(),获取(0)...拿到第一笛卡尔坐标。但是有时会采用通用的命名约定,并且一些方法名称在两个或多个库中是相同的。
我当然希望使用此代码对任何这些载体的,所以我实现了一个模板类。问题如下:如何使我的代码适应所有这些方法名称,而无需为每个实现专门设计我的类(某些方法名称相同)?
我设法编写使用的方法或其他,我现在想推广到任意数量方法的类。一些东西,说:“如果你有方法1,使用此实现,如果你有方法2,使用另一种,...如果你没有,那么编译错误”。模板类取决于模板参数方法
目前该类看起来像(缩小到部分拍摄随机方向):
// First some templates to test the presence of some methods
namespace detail_rand {
// test if a class contains the "setRThetaPhi" method
template<class T>
static auto test_setRThetaPhi(int) ->
decltype(void(std::declval<T>().setRThetaPhi(0.,0.,0.)),
std::true_type{});
template<class T>
static auto test_setRThetaPhi(float)->std::false_type;
}
// true_type if the class contains the "setRThetaPhi" method
template<class T>
struct has_setRThetaPhi : decltype(detail_rand::test_setRThetaPhi<T>(0)) {};
// The actual class
template<class vector>
class Random
{
// everything is static for easy use, might change later
private:
Random() = delete;
Random(Random&) = delete;
// the distribution, random generator and its seed
static decltype(std::chrono::high_resolution_clock::now().time_since_epoch().count()) theSeed;
static std::default_random_engine theGenerator;
static std::uniform_real_distribution<double> uniform_real_distro;
// Shoot a direction, the actual implementation is at the end of the file
private: // the different implementations
static const vector Dir_impl(std::true_type const &);
static const vector Dir_impl(std::false_type const &);
public: // the wrapper around the implementations
inline static const vector Direction() {
return Dir_impl(has_setRThetaPhi<vector>());
}
};
/// initialisation of members (static but template so in header)
// the seed is not of cryptographic quality but here it's not relevant
template<class vector>
decltype(std::chrono::high_resolution_clock::now().time_since_epoch().count())
Random<vector>::theSeed =
std::chrono::high_resolution_clock::now().time_since_epoch().count();
template<class vector>
std::default_random_engine Random<vector>::theGenerator(theSeed);
template<class vector>
std::uniform_real_distribution<double> Random<vector>::uniform_real_distro(0.,1.);
/// Implementation of method depending on the actual type of vector
// Here I use the "setRThetaPhi" method
template<class vector>
const vector Random<vector>::Dir_impl(std::true_type const &)
{
vector v;
v.setRThetaPhi(1.,
std::acos(1.-2.*uniform_real_distro(theGenerator)),
TwoPi()*uniform_real_distro(theGenerator));
return std::move(v);
}
// Here I use as a default the "SetMagThetaPhi" method
// but I would like to test before if I really have this method,
// and define a default implementation ending in a compilation error
// (through static_assert probably)
template<class vector>
const vector Random<vector>::Dir_impl(std::false_type const &)
{
vector v;
v.SetMagThetaPhi(1.,
std::acos(1.-2.*uniform_real_distro(theGenerator)),
TwoPi()*uniform_real_distro(theGenerator));
return std::move(v);
}
真棒回答!我希望我早点找到你的(顺便说一下)文章,我会节省几个小时。我明天一定会看你的视频! – gaFF