我正在阅读main json11 header file的源代码。
它包含以下声明:
template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {}
我试图在模板声明中找到一些关于decltype
和class
用法的文档,但没有成功。
这个构造/用法在C ++中是否有名称?关于它的任何好的参考?
答案 0 :(得分:1)
它正在使用SFINAE(“ S ubstitution F ailure 我 s N ot A n E rror“),这是高级模板内容的常用技巧。在这种情况下,它用作原始(1)测试类型T
是否具有名为to_json
的函数。
工作原理:如果表达式T::to_json
格式正确(to_json
类型中有T
的内容),decltype(T::to_json)
表示有效类型,构造函数模板可以正常使用。
但是,如果T::to_json
格式不正确(即如果to_json
内没有T
成员),则表示替换T
的模板参数失败。根据SFINAE,这不是整个程序的错误;它只是意味着模板被从进一步的考虑中删除(好像它从来不是该类的一部分)。
因此,如果类型T
具有成员to_json
,则可以使用类型为T
的对象来初始化Json
对象。如果T
中没有这样的成员,则构造函数将不存在。
(1)我说的是粗测试,因为这只会检查T
是否有这样的成员。它不会检查该成员是否是可以在没有参数的情况下调用的函数,并返回Json
的另一个构造函数可以接受的内容。更严格的测试可能看起来像这样:
template <class T, class = std::enable_if_t<std::is_constructible<Json, decltype(std::declval<const T>().to_json())>::value>>
Json(const T & t) : Json(t.to_json()) {}