gpt4 book ai didi

c++ SFINAE 检查指向类的指针中的方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:51:43 25 4
gpt4 key购买 nike

我有这样的代码:

template<class TABLELOADER = void>
class DiskFileFlush{
TABLELOADER *_loader;

public:
void process(){
// I want to call this,
// only if loader->refresh() exists.
notifyLoader();
}

bool notifyLoader(){
if (loader != nullptr)
return loader->refresh();

return false;
}
};

只有 loader->refresh() 存在时,我才想调用 notifyLoader()

我也使用 void 作为默认类型,有没有更好的方法来做同样的事情?

最佳答案

诀窍是同时使用 SFINAE 和模板特化。

以下示例使用 gcc 5.3 编译:

#include <iostream>

template<typename T> struct has_refresh_operator
{
//! Yes return value

typedef char yes[1];

//! No return value

typedef char no[2];

template<typename S>
static yes &check(decltype( (*(S *)nullptr)->refresh()) *);

template<typename S>
static no &check(...);

//! Determine whether the class implements ->refresh() method.

static const bool value = sizeof(check<T>(0)) == sizeof(yes);
};

// Now, use a specialized template to figure out what to do:

template<bool> class invoke_refresh;

template<> class invoke_refresh<true> {
public:

template<typename T>
static inline auto doit(const T &t)
{
return t->refresh();
}
};

template<> class invoke_refresh<false> {
public:
template<typename T>
static inline bool doit(const T &t)
{
return false;
}
};

// Now, let's try some examples:

template<class TABLELOADER = void>
class DiskFileFlush{
TABLELOADER *_loader;

public:

DiskFileFlush(TABLELOADER *p) : _loader(p) {}

void process(){
// I want to call this,
// only if loader->refresh() exists.
notifyLoader();
}

bool notifyLoader(){
if (_loader != nullptr)
return invoke_refresh<has_refresh_operator<TABLELOADER *>::value>::doit(_loader);
return false;
}
};

// Try: class implements refresh(), class doesn't implement refresh(),
// and a void pointer.

class foo1 {

public:
bool refresh()
{
std::cout << "Foo" << std::endl;
return true;
}
};

class foo2 {

public:
};

int main()
{
foo1 bar1;
foo2 bar2;

DiskFileFlush<foo1> foobar1(&bar1);
DiskFileFlush<foo2> foobar2(&bar2);
DiskFileFlush<void> baz(0);

foobar1.process();
foobar2.process();
baz.process();
}

关于c++ SFINAE 检查指向类的指针中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35682977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com