当前位置: 首页 > 知识库问答 >
问题:

扩展enable_if type以排除匹配的类型

萧嘉茂
2023-03-14

我使用这个神奇的标题来获得轻松序列化STL容器的能力。

然而,我现在已经开始为我的类型使用更高级的HTML序列化程序,我想做的部分工作是泛化操作符

这是我的(功能)尝试这样做(ohtmlstringstream::写是一个公共模板方法,它将其arg传递给私有成员stringstream运算符

namespace std {
    template<typename T>
    inline typename enable_if< ::pretty_print::is_container<T>::value, ohtmlstringstream&>::type
    operator<<(ohtmlstringstream& os, const T& container) {
        auto it = std::begin(container);
        const auto the_end = end(container);
        os.write("<div class='container'>");
        while(it != the_end) {
            os << *it;
            it++;
        }
        os.write("</div>");
        return os;
    }
}

我遇到的第一个问题是,任何时候在ohtmlstringstream上使用d::字符串时,它都被视为容器,这是我不想要的;我想把字符串视为只是字符串,而不是容器。当然,就pretty_print而言,std::字符串肯定是一个字符容器。

这是摘录自prettyprint.hpp

namespace pretty_print
{

    // SFINAE type trait to detect whether T::const_iterator exists.

    template<typename T>
    struct has_const_iterator
    {
    private:
        typedef char                      yes;
        typedef struct { char array[2]; } no;

        template <typename C> static yes test(typename C::const_iterator*);
        template <typename C> static no  test(...);
    public:
        static const bool value = sizeof(test<T>(0)) == sizeof(yes);
        typedef T type;
    };

    // SFINAE type trait to detect whether "T::const_iterator T::begin/end() const" exist.

    template <typename T>
    struct has_begin_end_OLD
    {
        struct Dummy { typedef void const_iterator; };
        typedef typename std::conditional<has_const_iterator<T>::value, T, Dummy>::type TType;
        typedef typename TType::const_iterator iter;

        struct Fallback { iter begin() const; iter end() const; };
        struct Derived : TType, Fallback { };

        template<typename C, C> struct ChT;

        template<typename C> static char (&f(ChT<iter (Fallback::*)() const, &C::begin>*))[1];
        template<typename C> static char (&f(...))[2];
        template<typename C> static char (&g(ChT<iter (Fallback::*)() const, &C::end>*))[1];
        template<typename C> static char (&g(...))[2];

        static bool const beg_value = sizeof(f<Derived>(0)) == 2;
        static bool const end_value = sizeof(g<Derived>(0)) == 2;
    };

    template <typename T>
    struct has_begin_end
    {
        template<typename C> static char (&f(typename std::enable_if<
                                             std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::begin)),
                                             typename C::const_iterator(C::*)() const>::value, void>::type*))[1];

        template<typename C> static char (&f(...))[2];

        template<typename C> static char (&g(typename std::enable_if<
                                             std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::end)),
                                             typename C::const_iterator(C::*)() const>::value, void>::type*))[1];

        template<typename C> static char (&g(...))[2];

        static bool const beg_value = sizeof(f<T>(0)) == 1;
        static bool const end_value = sizeof(g<T>(0)) == 1;
    };

    // Basic is_container template; specialize to derive from std::true_type for all desired container types

    template<typename T> struct is_container : public ::std::integral_constant<bool,
    has_const_iterator<T>::value && has_begin_end<T>::beg_value && has_begin_end<T>::end_value> { };

    template<typename T, std::size_t N> struct is_container<T[N]> : public ::std::true_type { };

    template<std::size_t N> struct is_container<char[N]> : public ::std::false_type { };

    template <typename T> struct is_container< ::std::valarray<T>> : public ::std::true_type { }; 

...<snip>

这里的问题是,我不清楚如何使用SFINAE和enable_if以及其他内容来构建另一个谓词,该谓词对除std::string之外的所有容器都求值为true。

这只是第一个问题。第二个问题是我的第一个代码清单中的一行,它是os。写(”

我想知道的是,是否存在一些(合理合理合理的)方法来使用模板实现这一点,或者我是否真的应该使用宏来显式定义一系列模板,每个STL容器类型一个:这样我就可以轻松地为任何给定容器构建我想要的确切类型的HTML。

确实,使用模板枚举所有STL容器可以解决这两个问题。我想我会开始这样做的。但我还是想知道最初第一个问题的答案。如果,如何使用启用\u排除特定类型?


共有1个答案

诸葛嘉熙
2023-03-14

添加代码

enable\u if的语法

如果您想要重用一个特性,只需创建一个继承自std::integral\u常量的特性

如果您完全支持C 11,请尝试编写一个constepr函数,该函数采用T类型,并返回true,而不是traits类。在C 1y中,当概念到达时,这可能很有用。

 类似资料:
  • 问题内容: 我正在尝试使用简单的Chrome扩展程序,但是在为数组提供值时遇到了问题。 当我尝试将此扩展程序加载到Chrome中时,收到以下消息: 无法从“ C:\ Users \ foo \ Desktop \ Extensions \ bar”加载扩展名。 “ content_scripts”的值无效。 我看不到我的值是什么“无效”。我想做的是匹配每个URL,以便我的扩展程序可以操纵它所运行的

  • 我试图在下面的填充()方法中填充一个列表,使用泛型来放松类型参数的限制,但我一直出错 类型列表中的add(int,capture#2-of?extends Number)方法不适用于参数(int) 当我尝试用编译器修复它时,它会自动用null填充列表。请问我该如何解决这个问题:

  • 我尝试通过以下方式为我的PageFactory创建存储: 因此,从代码部分您可以理解编译错误在哪里,尽管两者都是和从基本页扩展的T: 我必须从

  • 我正试图用三个额外的日期(时间戳)字段扩展扩展扩展名(新闻),并希望在(新闻)的fluidtemplate中调用这些字段。 我已经连线到目前为止,我可以看到我的后端额外的字段,而无需选择一个外部类型-我已经相应地修改了ext_tables.php,并可以保存数据。 现在,我试图在我的新闻流模板中使用这些字段,在我的Partials/List/Item中使用以下代码。html-{newsItem.d

  • 问题内容: 假设我有一个删除扩展名的方法,我需要两个变量的结果,一个是域名,另一个是扩展名。 我尝试过但不起作用,我猜只能用正则表达式.... 问题答案: 这将产生以下数组