使用带有 enable_if 的成员声明?

问题描述 投票:0回答:2

我需要有条件地使用成员声明。

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>
范围内可见?

c++ c++11 visual-studio-2012 visual-c++ visual-c++-2012
2个回答
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;
}

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) 的重复代码

如果

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;
};

移除那个丑陋的 bool

最后,要从

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.
};
© www.soinside.com 2019 - 2024. All rights reserved.