【问题标题】:Default value in constructor parameter based on template type基于模板类型的构造函数参数中的默认值
【发布时间】:2023-01-16 14:49:11
【问题描述】:

我有一个类如下

typename <int len, bool is_internal=false>
class MyClass
{
    int var;
    char* buffer;

    MyClass(int v, char* buff)
    {/* some logic that initializes buffer */}
};

我想要的是当in_internal 为真时,类构造函数不需要参数中的缓冲区值,但确保在is_internal 为假时提供该值。

我可以用 is_internal 作为类成员来做到这一点,但它会在构造函数中创建大量代码重复,我认为必须有一种更简洁的方法来使用模板或 constexpr 来做到这一点,并且在编译时由编译器。如果is_internal 为真,我还希望析构函数取消分配缓冲区。

编辑 - 这是我希望的,但在编译时以一种巧妙的方式来处理——

MyClass(int v, char* buff = nullptr)
{
    if(is_internal == true)
      assert(buff==nullptr);
    else
      assert(buff != nullptr);
    // rest of the common code.
}

【问题讨论】:

  • 您可以访问 C++20 吗?你可以写MyClass(int v, char* buff) requires !is_internalMyClass(int v) requires is_internal
  • @NathanPierson 的解决方案无需 c++20 即可工作,但需要一些不太漂亮的 SFINAE std::enable_if 技巧。
  • 我不想创建两个构造函数,因为它会导致大量代码重复。我还有其他依赖于此布尔值的函数。这就是我首先尝试使用模板的原因。
  • 你不能给一个函数两个签名。您可能可以通过将一个构造函数委托给另一个构造函数来摆脱困境……但是话又说回来,您可能不会。这在很大程度上取决于MyClass在做什么,以及MyClass&lt;x, true&gt;是否真的与MyClass&lt;x, false&gt;有那么多共同点。
  • 由于类代码将由编译器扩展,因此 is_internal 分别为 true/false。我想要一个用于错误案例的构造函数和一个用于真实案例的构造函数。

标签: c++ oop templates


【解决方案1】:

您不必创建 2 个完整的构造函数。您可以使用委托构造函数,如下所示:


#include <type_traits>

template<int len, bool is_internal=false>
class MyClass
{
    int var;
    char* buffer;

public:
    MyClass(int v, char* buff)
    {/* some logic that initializes buffer */}

    template<bool ii = is_internal>
    MyClass(std::enable_if_t<ii, int> v) : MyClass(v, nullptr) {}
};

int main()
{
    MyClass<10> a(5, nullptr);
    MyClass<20, true> b(8);
    //MyClass<30> c(9); // Error
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 2014-05-18
    • 2017-11-21
    • 2011-03-19
    相关资源
    最近更新 更多