#include <iostream>
using namespace std;
template<bool enable, typename T>
struct foo;
template<typename T>
struct foo<false , T>
{
//nothing
};
template<typename T>
struct foo<true , T>
{
void say_hello()
{
cout << "Hello !" << endl;
}
protected:
int m_some_data_when_I_enabled{};
};
template<bool Enable, typename T>
struct bar
:
foo<Enable , T>
{
//And there are lots of functions and members
//Here I need conditional 'using'
using foo<Enable , T>::say_hello;
void say_hello(int different_signature)
{
}
};
struct duck { };
int main(int, char**) {
bar<true , duck> enabled_bar;
bar<false , duck> disabled_bar;
}
当我声明bar时给出错误。对于我,这说得通。所以我需要类似的东西:
template<typename = typename std::enable_if<Enable>::type>
using foo<Enable , T>::say_hello();
我知道我可以解决“ bar”问题,但是它有一些成员,在这种情况下,我会重复很多代码。有其他不同的方法吗?
答案 0 :(得分:3)
您可以在第一个foo中声明已删除的say_hello
,从而使using
中的bar
语句合法。
template<typename T>
struct foo<false , T>
{
void say_hello() = delete;
};
Here是完整的示例。
答案 1 :(得分:0)
您可以添加一个简单的转发过载,并在成员不存在于基类中时使用SFINAE有条件地禁用它。像这样:
template<typename V = T, typename = decltype(&foo<Enable, V>::say_hello)>
void say_hello()
{
bar::foo::say_hello();
}
我们需要使用&foo<Enable, V>::say_hello
而不是&foo<Enable, T>::say_hello
来延迟检查并使其在替换期间(尝试调用该函数时)发生,而不是在{{1}时发生}实例化。
如果成员不存在,则重载解析将丢弃新的重载(由于格式不正确的替换),就好像它不存在一样。
但是值得注意的是,这不适用于过载集(因为不能将指针指向过载集的成员)。仅当您知道只有一个重载时,它才能工作,而重载可以明确地构成其成员指针。