如果一个类有一个具有给定签名的构造函数,我如何编译时检测?具体来说,我想做以下事情:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
有许多用于检测具有特定签名的功能的源.但是我无法将这些转换为构造函数. 源1 源2 源3等等.
从我发现的源代码中我编译了以下内容以检测函数是否具有plus运算符:
template<typename T>
using HasUnarchiveConstructorImpl = decltype(std::declval<T>() + std::declval<T>());
template< typename T >
using HasUnarchiveConstructor = std::is_detected<HasUnarchiveConstructorImpl, T>;
Run Code Online (Sandbox Code Playgroud)
如何将其扩展到我想要执行的检查?或者我怎么能以不同的方式做到这一点?
我有一组不同类的对象.我想迭代元组并仅在这些类有一个时才调用某个方法.
例如(伪代码):
struct A { int get( ) { return 5; }; };
struct B { };
struct C { int get( ) { return 10; }; };
int i = 0;
tuple<A, B, C> t;
for ( auto t_element : t )
{
if constexpr ( has_get_method( decltype(t_element) ) )
{
i += t_element.get( );
}
}
Run Code Online (Sandbox Code Playgroud)
我已经知道如何迭代元组并检查一个类是否有一些使用sfinae的方法但是如何跳过没有所需方法的对象?
使用 C++ 20 概念,我们可以这样写:
#define has_method(CLASS_NAME, METHOD_NAME) \ // Can be generalized of course, but it's just to illustrate the idea
[]<typename TEMPLATE_ARG>() \
{ \
return requires{ std::declval<TEMPLATE_ARG>().METHOD_NAME(); }; \
}.template operator()<CLASS_NAME>()
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
int main()
{
struct S{
void call_1();
void call_2();
void call_3();
void call_4();
};
static_assert(has_method(S, call_1)); // OK
static_assert(has_method(S, call_2)); // OK
static_assert(has_method(S, call_3)); // OK
static_assert(has_method(S, call_4)); // OK
static_assert(has_method(S, call_5)); // Error
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以在has_method没有概念的情况下实现宏(即仅使用 C++17)?
更清楚地说:我需要一个可以接受类和方法名称的宏,我想在 constexpr 上下文中使用这样的宏,就像 constexpr 函数一样。标准 SFINAE 实现需要创建至少两个模板结构,这使得很难(或不可能)将所有这些都放入一个宏中。所以我的问题是否实际上是不可能的。
// First try this:
template <class T> T Read(istream& in) {
T t;
in >> t;
return t;
}
// If there is no operator>>(istream&, T) try this:
template <class T> T Read(istream& in) {
return T (in);
}
// If there is no constructor T(istream&) try this:
template <class T> T Read(istream& in) {
return T::OfStream (in);
}
// now fail.
Run Code Online (Sandbox Code Playgroud)
这可以实施吗?
如果没有,有哪些替代方案?
是否有可能在C创建的模板++(11),用于一个函数来检查对象是否包含在任何一个std::vector,std::array或std::list(以及可能甚至更多的容器类型)?
我现在有什么:
typedef std::shared_ptr<Tag> SharedTag;
typedef std::vector<SharedTag> TagList;
bool
Tag::isIn(const TagList& lst) {
return std::any_of(lst.begin(), lst.end(), [this](const SharedTag& t) {
return t->name == this->name;
});
}
Run Code Online (Sandbox Code Playgroud)
Tag是正常的class.当然,应该进行比较,t == this这将是operator==后来的比较.为简单起见,我没有在此处包含此内容.
那么,是不是可以写上代码只有一次(不包括的typedef的虽然)为std::vector,std::array,std::list(,也许对std::set)等?
我找不到所有这些类的基类型......这将是我的第一个想法......