C++17下如何实现is_explicitly_constructible类型萃取
C++17 实现显式构造检测类型萃取trait
实现思路
- 核心逻辑:显式可构造 = 支持直接构造(用
std::is_constructible判断)且不支持隐式构造 - 隐式构造的检测利用「返回值为
T的函数能否接收花括号初始化参数列表做入参」的特性:explicit构造函数不允许隐式转换,因此该场景下会编译失败,通过SFINAE即可区分两种构造场景
完整实现代码
#include <type_traits> #include <utility> namespace detail { // 检测隐式构造可行的重载 template <typename T, typename... Args> auto test_implicit(int) -> decltype( static_cast<void>(std::declval<T(&)(Args...)>()({std::declval<Args>()...})), std::true_type{} ); // 隐式构造不可行时的fallback重载 template <typename T, typename... Args> auto test_implicit(long) -> std::false_type; } // namespace detail template <typename T, typename... Args> constexpr bool is_implicitly_constructible_v = decltype(detail::test_implicit<T, Args...>(0))::value; template <typename T, typename... Args> struct is_explicitly_constructible { static inline constexpr bool value = std::is_constructible_v<T, Args...> && !is_implicitly_constructible_v<T, Args...>; }; // 可选的辅助变量模板,方便使用 template <typename T, typename... Args> inline constexpr bool is_explicitly_constructible_v = is_explicitly_constructible<T, Args...>::value;
测试验证
#include <iostream> struct Foo { Foo(void*, void*) {} explicit Foo(int, int) {} }; int main() { std::cout << std::boolalpha; std::cout << is_explicitly_constructible<Foo, void*, void*>::value << std::endl; std::cout << is_explicitly_constructible<Foo, int, int>::value << std::endl; }
输出结果和预期完全一致:
false true
内容的提问来源于stack exchange,提问作者marinno
相关产品推荐
相关产品推荐

