检测 class 是否具有带签名的构造函数
Detect if class has constructor with signature
我如何在编译时检测 class 是否具有具有给定签名的构造函数?具体来说,我想执行以下操作:
class Archive
{
// (...)
template <typename T>
T Read()
{
if constexpr(HasUnarchiveConstructor<T>())
{
return T(*this); // constructor accepts reference to Factory
}
else
{
T t;
Unarchive(*this, t); // use stand alone function instead. (if this is not available either, compiling fails)
return t;
}
}
}
有许多来源可用于检测具有特定签名的函数。但是我无法将它们转换为构造函数。
source 1 source 2 source 3,等等。
根据我发现的来源,我编译了以下内容以检测函数是否具有加号运算符:
template<typename T>
using HasUnarchiveConstructorImpl = decltype(std::declval<T>() + std::declval<T>());
template< typename T >
using HasUnarchiveConstructor = std::is_detected<HasUnarchiveConstructorImpl, T>;
如何将其扩展到我要执行的检查?或者我怎样才能以不同的方式做到这一点?
How can I extend this to the check I want to perform?
您可以在 T{...}
表达式上使用 decltype(...)
,如下所示:
struct Foo
{
Foo(Archive&) { }
};
struct Bar
{
// unsupported
};
template<class T>
using HasUnarchiveConstructorImpl =
decltype(T{std::declval<Archive&>()});
template <class T>
using HasUnarchiveConstructor =
std::experimental::is_detected<HasUnarchiveConstructorImpl, T>;
static_assert(HasUnarchiveConstructor<Foo>::value);
static_assert(!HasUnarchiveConstructor<Bar>::value);
Or how can I do it in a different way?
参见 Howard Hinnant 的 。
我会使用:
if constexpr(std::is_constructible<T, Archive&>{})
此特性存在于 <type_traits>
中,并已为您调试好。那里有一整套特征可以检测这个问题的变体。
template <class T>
using HasUnarchiveConstructor = std::is_constructible<T, Archive&>;
我如何在编译时检测 class 是否具有具有给定签名的构造函数?具体来说,我想执行以下操作:
class Archive
{
// (...)
template <typename T>
T Read()
{
if constexpr(HasUnarchiveConstructor<T>())
{
return T(*this); // constructor accepts reference to Factory
}
else
{
T t;
Unarchive(*this, t); // use stand alone function instead. (if this is not available either, compiling fails)
return t;
}
}
}
有许多来源可用于检测具有特定签名的函数。但是我无法将它们转换为构造函数。 source 1 source 2 source 3,等等。
根据我发现的来源,我编译了以下内容以检测函数是否具有加号运算符:
template<typename T>
using HasUnarchiveConstructorImpl = decltype(std::declval<T>() + std::declval<T>());
template< typename T >
using HasUnarchiveConstructor = std::is_detected<HasUnarchiveConstructorImpl, T>;
如何将其扩展到我要执行的检查?或者我怎样才能以不同的方式做到这一点?
How can I extend this to the check I want to perform?
您可以在 T{...}
表达式上使用 decltype(...)
,如下所示:
struct Foo
{
Foo(Archive&) { }
};
struct Bar
{
// unsupported
};
template<class T>
using HasUnarchiveConstructorImpl =
decltype(T{std::declval<Archive&>()});
template <class T>
using HasUnarchiveConstructor =
std::experimental::is_detected<HasUnarchiveConstructorImpl, T>;
static_assert(HasUnarchiveConstructor<Foo>::value);
static_assert(!HasUnarchiveConstructor<Bar>::value);
Or how can I do it in a different way?
参见 Howard Hinnant 的
我会使用:
if constexpr(std::is_constructible<T, Archive&>{})
此特性存在于 <type_traits>
中,并已为您调试好。那里有一整套特征可以检测这个问题的变体。
template <class T>
using HasUnarchiveConstructor = std::is_constructible<T, Archive&>;