条件使用声明
conditional using declaration
#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' 来解决问题,但它有一些成员,在那种情况下我会重复很多代码。有没有不同的,也许是棘手的方法?
您可以在第一个 foo 中声明删除 say_hello
,这使得 bar
中的 using
语句合法。
template<typename T>
struct foo<false , T>
{
void say_hello() = delete;
};
Here 是完整示例。
您可以添加一个简单的转发重载,并在成员不存在于基class 时使用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
来延迟检查并使其在替换期间发生(当尝试调用函数时)而不是在 [= 时发生13=] 被实例化。
如果成员不存在,重载决策将丢弃新的重载(由于 ill-formed 替换),就好像它从未存在过一样。
但值得注意的是,这不适用于重载集(因为不能采用 pointer-to-member 的重载集)。它只有在你知道只有一个重载时才有效,它可以明确地形成 pointer-to-member。
#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' 来解决问题,但它有一些成员,在那种情况下我会重复很多代码。有没有不同的,也许是棘手的方法?
您可以在第一个 foo 中声明删除 say_hello
,这使得 bar
中的 using
语句合法。
template<typename T>
struct foo<false , T>
{
void say_hello() = delete;
};
Here 是完整示例。
您可以添加一个简单的转发重载,并在成员不存在于基class 时使用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
来延迟检查并使其在替换期间发生(当尝试调用函数时)而不是在 [= 时发生13=] 被实例化。
如果成员不存在,重载决策将丢弃新的重载(由于 ill-formed 替换),就好像它从未存在过一样。
但值得注意的是,这不适用于重载集(因为不能采用 pointer-to-member 的重载集)。它只有在你知道只有一个重载时才有效,它可以明确地形成 pointer-to-member。