如果我正在编写一个将参数转发给构造函数的通用函数,有没有办法判断它是否是一个复制构造函数?基本上我想做:
template <typename T, typename... Args>
void CreateTAndDoSomething(Args&&... args) {
// Special case: if this is copy construction, do something different.
if constexpr (...) { ... }
// Otherwise do something else.
...
}
Run Code Online (Sandbox Code Playgroud)
我想出的最好的方法是检查sizeof...(args) == 1然后查看std::is_same_v<Args..., const T&> || std::is_same_v<Args..., T&>. 但我认为这错过了边缘情况,例如 volatile 限定的输入和隐式转换为T.
老实说,我不完全确定这个问题是明确定义的,所以请随时告诉我它不是(以及为什么)。如果它有帮助,您可以假设唯一的单参数构造函数T是T(const T&)and T(T&&)。
如果我认为这没有明确定义是对的,因为复制构造函数不是事物,那么也许可以通过说“我如何判断表达式是否T(std::forward<Args>(args)...)选择接受的重载const T&?
您可以使用remove_cv_t:
#include <type_traits>
template <typename T, typename... Args>
void CreateTAndDoSomething(Args&&... args) {
// Special case: if this is copy construction, do something different.
if constexpr (sizeof...(Args) == 1 && is_same_v<T&, remove_cv_t<Args...> >) { ... }
// Otherwise do something else.
...
}
Run Code Online (Sandbox Code Playgroud)
这涵盖了标准定义的所有“复制构造函数” ,不考虑可能的默认参数(很难确定给定的函数参数(对于给定这些参数将调用的函数)是否是默认的)。