继续问一个 C++里的模板问题

2015-10-08 21:27:06 +08:00
 iambic

主要是 is_constructible 的使用问题

class Json{
    // Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
    template <class M, typename std::enable_if<
        std::is_constructible<std::string, typename M::key_type>::value
        && std::is_constructible<Json, typename M::mapped_type>::value,
            int>::type = 0>
    Json(const M & m) : Json(object(m.begin(), m.end())) {}

    // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
    template <class V, typename std::enable_if<
        std::is_constructible<Json, typename V::value_type>::value,
            int>::type = 0>
    Json(const V & v) : Json(array(v.begin(), v.end())) {}
    ...
};

这两个构造函数,第一个是说,接受一个类似 map 的东西。这个我大概能看明白
第一个 is_contructible 是说, class M 里边需要定义 M::key_type 这种类型,而且这种类型可以用来初始化 std::string
即 std::string(M::key_type), 显然 M::key_type 只能是 std::string 或者 const char*
第二个类似,要求 class M 里边还要定义 M::mapped_type ,并且这种类型可以用来初始化 Json, 根据之前的定义,这种 M::mapped_type 包括 string, array, object, boolean 等等。

总之,这样的 M 大概就是类似 map 或者 unordered_map 这个样子。 key 是 string , value 是其他可以用来初始化 Json 的类型。

但是第二个构造函数就看不太明白了,看注释是说,接受一个类似 vector 的对象,包括 list,vector,set 等。

std::is_constructible<Json, typename V::value_type>::value,int>

这个应该是说, class V 首先内部需要有一个 value_type 的类型,同时 value_type 和 int 可以用来共同初始化 Json ,即要求
Json(V::value_type, int)这样的构造函数是合法的。

为了让问题明确,我把 class Json 所有的构造函数全部列了出来,似乎没有看到哪个构造函数有
Json(V::value_type, int)这样的形式。。

那上边第二个构造函数,到底是怎么来要求,输入的 class V 是 vector 类似的类型的呢?
谢谢!

附,以下是 class Json 所有的构造函数。

class Json final {
public:
    // Types
    enum Type {
        NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT
    };

    // Array and object typedefs
    typedef std::vector<Json> array;
    typedef std::map<std::string, Json> object;

    // Constructors for the various types of JSON value.
    Json() noexcept;                // NUL
    Json(std::nullptr_t) noexcept;  // NUL
    Json(double value);             // NUMBER
    Json(int value);                // NUMBER
    Json(bool value);               // BOOL
    Json(const std::string &value); // STRING
    Json(std::string &&value);      // STRING
    Json(const char * value);       // STRING
    Json(const array &values);      // ARRAY
    Json(array &&values);           // ARRAY
    Json(const object &values);     // OBJECT
    Json(object &&values);          // OBJECT

    // Implicit constructor: anything with a to_json() function.
    template <class T, class = decltype(&T::to_json)>
    Json(const T & t) : Json(t.to_json()) {}

    // Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
    template <class M, typename std::enable_if<
        std::is_constructible<std::string, typename M::key_type>::value
        && std::is_constructible<Json, typename M::mapped_type>::value,
            int>::type = 0>
    Json(const M & m) : Json(object(m.begin(), m.end())) {}

    // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
    template <class V, typename std::enable_if<
        std::is_constructible<Json, typename V::value_type>::value,
            int>::type = 0>
    Json(const V & v) : Json(array(v.begin(), v.end())) {}

    // This prevents Json(some_pointer) from accidentally producing a bool. Use
    // Json(bool(some_pointer)) if that behavior is desired.
    Json(void *) = delete;
2141 次点击
所在节点    问与答
2 条回复
hyq
2015-10-09 01:03:02 +08:00
“同时 value_type 和 int 可以用来共同初始化 Json ,即要求 Json(V::value_type, int)这样的构造函数是合法的。”
这个 int 哪来的,是不是 enable_if 的第二个参数?
iambic
2015-10-09 10:58:43 +08:00
@hyq 0 0 确实是我看错了

int 确实应该是 enable_if 的第二个参数。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/226425

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX