我需要使用成员声明的条件。
template <bool> struct B;
template <> struct B<true> { void foo(); };
template <> struct B<false> { };
template <typename T>
struct A : public B<is_default_constructible<T>::value> {
using B<is_default_constructible<T>::value>::foo();
void foo(int) {}
};
这显然不起作用,因为B<bool>::foo
未定义
一半的情况。我怎样才能做到这一点?拥有B<>::foo()
在foo(int)旁边的A<T>
范围内可见?
感谢您的帮助
答案 0 :(得分:0)
这是我的解决方案。我相信它不会是最好的,但它可以完成工作。
struct A {
void foo(int) {}
};
struct A
应包含您希望在两种情况下定义的方法。
template <bool> struct B;
template <> struct B<false> : A {};
template <> struct B<true> : A {
using A::foo;
void foo() {}
};
如果是B<false>
,则只定义void foo(int)
。如果是B<true>
,则void foo(int)
和void foo()
都已定义。
template <typename T>
struct C : public B<is_default_constructible<T>::value> {};
现在我不必担心在某些情况下B<is_default_constructible<T>::value>::foo()
没有被定义。
class D { D() = delete; };
int main()
{
C<int> c1;
c1.foo(1234);
c1.foo();
// both methods are defined for C<int>
C<D> c2;
c2.foo(1234);
// c2.foo(); // undefined method
return 0;
}
答案 1 :(得分:0)
enable_if
不能用于此。您还需要专门化struct A
。
#include <type_traits>
template <bool> struct B;
template <> struct B<true> { void foo(); };
template <> struct B<false> { };
template <typename T, bool default_constructible = std::is_default_constructible<T>::value>
struct A : public B<default_constructible> {
using B<default_constructible>::foo;
void foo(int) {}
};
template<typename T>
struct A<T, false> : public B<false> {
void foo(int) {}
};
如果foo(int)
在两种情况下具有相同的功能,您可能希望从另一个基础结构派生它:
#include <type_traits>
template <bool> struct B;
template <> struct B<true> { void foo(); };
template <> struct B<false> { };
template<typename T>
struct C {
void foo(int) {}
};
template <typename T, bool default_constructible = std::is_default_constructible<T>::value>
struct A : public B<default_constructible>, public C<T> {
using B<default_constructible>::foo;
using C<T>::foo;
};
template<typename T>
struct A<T, false> : public B<false>, public C<T> {
using C<T>::foo;
};
最后,要从struct A
的模板参数中删除该bool,您可能希望将选择foo
的重载的责任转发给基类。这样做的好处是不会复制您可能想要添加的其他struct A
成员的代码。
#include <type_traits>
template <bool> struct B;
template <> struct B<true> { void foo(); };
template <> struct B<false> { };
template<typename T>
struct C {
void foo(int) {}
};
template <typename T, bool default_constructible = std::is_default_constructible<T>::value>
struct base_A : public B<default_constructible>, public C<T> {
using B<default_constructible>::foo;
using C<T>::foo;
};
template<typename T>
struct base_A<T, false> : public B<false>, public C<T> {
using C<T>::foo;
};
template <typename T>
struct A : public base_A<T> {
// Other members.
};