![](/img/trans.png)
[英]Template specialisation with enable_if and is_arithmetic for a class
[英]template struct tag partial specialisation with enable_if or something similar
我正在寻找一种方法来使用std :: enable_if或类似的东西来扩展已经存在的自定义点,它将像下面的A<T>
一样工作(只是一个虚拟的例子):
// customisation point structure in external lib
template<typename T>
struct A
{
typedef T type;
};
//---------------------------------------------
#include <vector>
template <typename T>
concept bool Floating = std::is_floating_point<T>::value;
// specialisation with enable_if style that doesn't require change to external lib
template<Floating T>
struct A<T>
{
typedef std::vector<T> type;
};
int main()
{
static_assert(std::is_same<A<int>::type, int>::value, "");
static_assert(std::is_same<A<float>::type, std::vector<float>>::value, "");
return 0;
}
问题是我有以下限制:
template<typename T, typename = void>
因为此结构是在外部库中定义的 A<type_mod<float>>
因为这样会很丑陋且容易出错(宏观使用同样如此) 我怀疑这是可能的,但我记得过去的人说不需要概念精简版,因为它们或多或少可以用元编程模拟,所以我希望有人可以证明我错了。
为了确保我正确理解这个问题,你是在寻找与你发布的代码相当的东西,但只使用C ++ 14(没有概念)?
我认为你提到的第一个限制(“结构A不能被修改为接受两个模板参数”)是最大的问题。 我不知道有任何方法可以在不使用概念的情况下同时为整个“类”类型(例如浮点类型)专门化现有的单参数模板。
所以我认为对你的问题的严格回答是,“不,这是不可能的。”
如果你可以修改A的第一个声明,那么它会容易得多。 就个人而言,我觉得有时候对“我无法修改这个外部库”的问题的最佳答案是“去看看如何修改它,然后回来再问你的问题。”
我在下面提供了一个替代解决方案的想法,但是您的问题中缺少太多信息,无法说明它是否适合您。
我假设这个外部库提供了一些你提供的标题,以便查看你的专业化,并且每当你更改那个标题时你都会重新编译库。 (如果情况并非如此,请编辑您的问题以更好地解释情况。)
在你想要专业化的同一个标题中,你可以考虑使用一些老式的预处理器技巧作为解决方法。 这很丑陋,你必须小心你的#include
语句的顺序,但它可能会为你完成工作:
// customisation point structure in external lib
template<typename T>
struct A
{
typedef T type;
};
//---------------------------------------------
#include <vector>
template<typename T, bool is_float>
struct Av2impl
{
typedef T type;
};
template<typename T>
struct Av2impl<T, true>
{
typedef std::vector<T> type;
};
template<typename T>
struct Av2
{
typedef typename Av2impl<T, std::is_floating_point<T>::value>::type type;
};
// force all code after this point to use Av2 instead of A
#define A Av2
int main()
{
static_assert(std::is_same<A<int>::type, int>::value, "");
static_assert(std::is_same<A<float>::type, std::vector<float>>::value, "");
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.