关于隐式构造函数的json11库的代码说明

时间:2017-08-15 12:04:34

标签: c++11 templates decltype

我正在阅读main json11 header file的源代码。

它包含以下声明:

template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {}

我试图在模板声明中找到一些关于decltypeclass用法的文档,但没有成功。

这个构造/用法在C ++中是否有名称?关于它的任何好的参考?

1 个答案:

答案 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()) {}

[Live example]