源自 this主题.也与此 topic有关.
我的问题是为什么std :: is_constructible会在紧邻的上下文中停止?我认为std :: is_constructible的用户会希望它能够全面运行并给出确切的答案.有了这个直接上下文的东西,你可能有std :: is_constructible给你一个绿灯,只是为了在你真正做到这一点时得到一个硬编译错误.这不会破坏std :: is_constructible的原始目标和目的.现在,它对我来说基本上看起来毫无用处.我猜std :: looks_constructible_at_first_sight将是当前语义的更好名称:(
最佳答案 如果你的构造函数的签名比它应该更宽松,那就是问题 – 而不是is_constructible的实现.在您的原始示例中,
template <typename... Ts, typename=decltype(base{std::declval<Ts>()...})>
aggregate_wrapper(Ts&&... xs)
: base{std::forward<Ts>(xs)...} {/*…*/}
做的工作.如果is_constructible“spuriously”给出了绿灯,那么你的构造函数模板可能会被虚假地选择而不是其他构造函数,因为重载决策会发现它是最佳匹配.
但是,重载决策不是为了给出真正的否定/肯定:它被设计为在给定适当参数的情况下找到最佳匹配,或者如果参数足够不合适则不产生任何结果. is_constructible在某种意义上可能是肤浅的,但这就是特征所在 – 检查签名,这是一个实体在重载决策和SFINAE领域的表示 – 不会阻止你的函数模板接受所有东西,只是实际上只是实际实例化了一小部分参数.
这是你的责任,如果你遇到它,你将从is_constructible和高效的编译中获得适当的结果.这绝对比在函数模板调用中具有众多隐藏规则的is_constructible和高编译时间的可靠操作更好.