【问题标题】:Can I insert various typed elements into a container?我可以在容器中插入各种类型的元素吗?
【发布时间】:2021-10-01 19:41:35
【问题描述】:

我尝试使用如下模板引发堆栈溢出:

#include <iostream>

using namespace std;

#define endl '\n'

template <class T>
// void next (T a) cout << a++ << endl;       // can't write in a line without {}
void next (T a)
{
    if (typeid(a) == typeid((char) 'a') || typeid(a) == typeid((unsigned char) 'a'))
    {
        cout << typeid(a).name() << " : " << (int) a << " + 1 = " << (int) ++a << " (converted to ASCII value)" << endl;    
    } else
    {
        cout << typeid(a).name() << " : " << a << " + 1 = " << ++a << endl;
    }
    // there will be more alternatives like type_info and so on ……
}

int main()
{
    next((char) CHAR_MAX);
    next((unsigned char) UCHAR_MAX);
    next((short) SHRT_MAX);
    next((unsigned short) USHRT_MAX);
    next((int) INT_MAX);
    next((unsigned int) UINT_MAX);
    next((bool) 1);                     // warning: use of an operand of type 'bool' in 'operator++' is deprecated

    return 0;
}
  • 结果:
c : 127 + 1 = -128 (converted to ASCII value)
h : 255 + 1 = 0 (converted to ASCII value)
s : 32767 + 1 = -32768
t : 65535 + 1 = 0
i : 2147483647 + 1 = -2147483648
j : 4294967295 + 1 = 0
b : 1 + 1 = 1

这是我之前的高级代码,它为每种数据类型重载了类似的函数(太遗憾了,所以应该保密)。

但是现在我有更多的问题,我是否可以在main() 中压缩next() 的系列更多。我认为它似乎需要一个可以包含各种类型数据的容器;例如,{short 1, int 10, long long 100}

感谢您的建议,最重要的是,请注意您的健康。

【问题讨论】:

  • 您似乎以错误的方式学习 C++。您的术语似乎错误且令人困惑。这个问题非常不清楚。我不知道你在问什么。
  • 好吧,我的意思是找到一些比重复使用next() 更有效的方法。所以我想,如果有一个容器可以有各种类型的元素,我可以很容易地在for循环中替换它。
  • 如果我没看错的话,听起来你想要一个std::tuple,然后使用this 为元组的每个元素调用一个函数。

标签: c++ types stl containers


【解决方案1】:

确实,我不知道你在问什么,所以我试着回答一些相关的问题,希望这会有所帮助:)

要查找T 类型的最大值,请使用numeric_limits&lt;T&gt;::max() 函数而不是宏。这样你只能指定类型来调用你的函数:

next<char>();
next<unsigned char>();
next<short>();
...

在函数next 中,我可以看到您如何以特殊方式处理char 类型。有一个巧妙的技巧可以使您免于使用if。表达式+a(一元加号)触发整数提升,因此至少会生成int,它可以正确打印为数字。所以你可以像这样重写next

template <class T>
void next()
{
  T a = std::numeric_limits<T>::max();
  T b = a + 1;
  std::cout << typeid(T).name() << " : " << +a << " + 1 = " << +b << std::endl;
}

回答您最初的问题,现在当您在 next 的调用中摆脱宏时,您可以“迭代”调用它的类型。在 c++ 中,如果您需要“类型集合”T1T2T3,通常使用std::tuple&lt;T1, T2, T3&gt;。然而,在这种不需要将这个“集合”存储在任何地方的特殊情况下,使用可变参数模板和折叠表达式实际上更容易:

template<class... Ts>
void print() {
    (next<Ts>(), ...);
}

int main()
{
  print<char, unsigned char, short, int>();
}

注意表达式(next&lt;Ts&gt;(), ...); 是如何扩展为(next&lt;char&gt;(), next&lt;unsigned char&gt;(), next&lt;short&gt;(), next&lt;int&gt;()); 的。这是由运算符逗号分隔的多个调用。

最后一点,使用++aa+1 查找“下一个”数字是不正确的,因为溢出有符号整数类型是未定义的行为。你不一定会得到预期的结果。

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 2015-03-26
    • 2016-09-29
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 2020-08-22
    • 2017-07-26
    相关资源
    最近更新 更多