【问题标题】:How can I create a C++ basic type that self-initializes?如何创建自初始化的 C++ 基本类型?
【发布时间】:2013-08-28 08:18:45
【问题描述】:

相关问题:std::map default value for build-in type -- 细微的差别是我想知道值是初始化为0 还是垃圾,我想指定一个“构造函数”。我什至不在乎它是否涉及类定义的开销,我只想要一个干净的“特殊”基本类型。即使是语法黑客也可以。非基本类型很容易做到这一点,因为它是构造函数的全部工作。

我想要一个哈希图unordered_map<void *, int>,但要将其所有值默认初始化为-1,而不是0 或垃圾。这是因为零是一个有效的索引,我更愿意用一个肯定无效的值进行默认初始化。

我想我看到了一些草率的方法:

struct minus1 {
    int i; 
    minus1() i(-1) {}
};
unordered_map<void*, minus1>

但我不喜欢这样,因为我必须使用 .i 来访问 int,而且它真的只需要是一个 int。

好吧,也许我可以让我的地图处理这个:

struct PointerToIDHash {
    std::unordered_map<void *, int> h;
    PointerToIDHash() {
        // ctor is powerless to affect the initialized values of future insertions into h
    }
};

好吧,废话,现在我也有一个.h。嗯。我可以从模板继承吗? (听起来很吓人,但如果可以取消,这可能是一种干净的方式)

如何创建一个透明地像 int 一样但始终初始化为 -1 的类型?

我更希望知道如何使用和不使用 C++11。

【问题讨论】:

  • 您是否考虑过提供转换运算符?
  • 那是什么? :) 告诉我更多。
  • 看看 a.lasram 的回答。这基本上就是我的意思。
  • 甜蜜。我知道有一些事情可以做到这一点!
  • 不解决初始化问题。相反,解决您希望使用无效索引值初始化int 的问题。此功能已经存在,称为boost::optional。然后您不必使用特殊的 int 值来表示它未初始化,您只需检查可选项是否已初始化。

标签: c++ c++11


【解决方案1】:
#include <unordered_map>
#include <iostream>

using namespace std;

template<typename T, T default_value>
class SelfInitializer
{
public:
    SelfInitializer(T x = default_value) : x(x) {}
    operator T&() { return x; }
    operator const T&() const { return x; }
private:
    T x;
};

// demo
int main()
{
    using minus1 = SelfInitializer<int, -1>;

    unordered_map<int, minus1> m;

    m[7] = 3; // assignment works

    minus1 x = 3;

    int y = x; // conversion to int works

    int z = int(x); // explicit conversion works

    cout << m[7] << endl;
}

【讨论】:

  • operator= 有用吗? my_map[7] = 3 然后就可以工作了。
  • @user1131467 你能告诉我如何在ostream&amp; operator &lt;&lt; (ostream&amp; os, const minus1&amp; i) 函数中使用它吗?我正在使用os &lt;&lt; int(i);,但它似乎不干净。
  • @StevenLu:你不需要定义这样的函数,operator&lt;&lt;(ostream&amp;, int) 已经从operator T&amp; 中提取了它。有关演示,请参见演示的最后一行。
【解决方案2】:

将转换运算符添加到 int&amp; 以便您的结构 minus1 表现得像一个 int

struct minus1 {
    int i; 
    minus1() : i(-1) {}
    operator int&() { return i; }
};

【讨论】:

  • 您可能还需要一个转换构造函数。 minus1(int n) : i(n) {} [或结合默认构造函数,minus1(int n=-1) : i(n) {}.]
  • @aschepler 是的,编译器告诉了我很多 :)
  • int&amp; operator=(int o) 这样你就可以分配给它,复制构造,.get(),当你真的需要显式转换时,operator int const&amp;() const
  • @Yakk 是的,这将完成 user1131467 的回答;我的没有详细说明,仅限于“不使用”.i
  • @Yakk:分配已经在两种解决方案中都有效。要显式转换,您可以在两种解决方案中使用 int(x)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多