繁体   English   中英

模板struct标签部分特化与enable_if或类似的东西

[英]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;
}

问题是我有以下限制:

  • struct A无法修改为接受两个模板参数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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM