gpt4 book ai didi

c++ - 模板:在运行时从(并引用)非类型参数实例化?

转载 作者:搜寻专家 更新时间:2023-10-31 01:59:03 29 4
gpt4 key购买 nike

我开发了一个通用的“未签名”类,或者实际上是一个类模板 Unsigned<size_t N>它使用 uint8_t 的数量在 C (C++) 内置无符号数之后建模s 作为参数。例如Unsigned<4>uint32_t 相同和 Unsigned<32>将与 uint256_t 相同-- 如果它存在。

到目前为止,我已经设法遵循了大部分(如果不是全部的话)来自内置无符号符号的预期语义——特别是 sizeof(Natural<N>)==N。 , (Natural<N>(-1) == "max_value_all_bits_1" == ~Natural<N>(0)) ,与 abs()、sign()、div(使用自定义 div_t 结构)、ilogb()(似乎是 GCC 独有的)和 numeric_limits<> 的兼容性。

但是我面临的问题是,因为 1.- 类模板只是一个模板,所以模板化形式是不相关的,并且 2.- 模板非类型化参数需要一个“编译时常量”,它是比“a const”更严格,我基本上无法在给定未知 N 的情况下创建 Unsigned

换句话说,我不能有这样的代码:

...
( ... assuming all adequate headers are included ...)
using namespace std;
using lpp::Unsigned;
std::string str;
cout<< "Enter an arbitrarily long integer (end it with <ENTER>) :>";
getline(cin, str, '\n');
const int digits10 = log10(str.length()) + 1;
const int digits256 = (digits10 + 1) * ceil(log(10)/log(256)); // from "10×10^D = 256^T"
// at this point, I "should" be able to, semantically, do this:
Unsigned<digits256> num; // <-- THIS I CAN'T -- num would be guaranteed
// big enough to hold str's binary expression,
// no more space is needed
Unsigned::from_str(num, str); // somehow converts (essentially a base change algo)
// now I could do whatever I wanted with num "as if" a builtin.
std::string str_b3 = change_base(num, 3); // a generic implemented somehow
cout<< "The number above, in base 3, is: "<< str_b3<< endl;
...

(A/N——这是 Unsigned 测试套件的一部分,它读取一个“稍大的数字”(我已经尝试了最多 120 位数字——在相应地设置 N 之后)并且做一些事情,比如在其他基础上表达它,它本身已经测试了所有算术函数。)

在寻找绕过或以其他方式减轻此限制的可能方法时,我遇到了一些我想尝试和探索的概念,但我不想花太多精力在替代方案上会使事情变得更复杂,或者会使类的行为偏离太多。

我首先想到的是,如果我无法拿起 Unsigned<N>根据我的选择,我至少可以从一组预选的 N 值中选取,这将导致在运行时调用足够的构造函数,但取决于编译时值:

???? GetMeAnUnsigned (size_t S) {
switch (S) {
case 0: { throw something(); } // we can't have a zero-size number, right?
case 1, 2, 3, 4: { return Unsigned<4>(); break; }
case 5, 6, 7, 8: { return Unsigned<8>(); break; }
case 9, 10, 11, 12, 13, 14, 15, 16: { return Unsigned<16>(); break; }
....
default: { return Unsigned<128>(); break; } // wow, a 1Kib number!
} // end switch
exit(1); // this point *shouldn't* be reachable!
} // end function

我个人喜欢这种方法。但是我不知道我可以用什么来指定返回类型。它实际上并没有“解决”问题,只是在一定程度上降低了问题的严重性。我敢肯定,使用 switch 的技巧是可行的,因为实例化来自编译时常量,它只会更改 哪些 将发生。

声明返回类型的唯一可行帮助似乎是这个新的 C++0(1?)X "decltype"构造,它允许我获得足够的类型,比如,如果我正确理解了该功能:

decltype (Unsigned<N>) GetMeAnUnsigned (size_t S) {
.. do some choices that originate an N
return Unsigned<N>();
}

... 或类似的东西。我还没有进入 C++?X beyond auto (对于迭代器)还没有,所以第一个问题是:会像 decltype 这样的功能吗?或 auto帮助我实现我想要的?(运行时实例化的选择,即使有限)

作为替代方案,我在想,如果问题出在我的类之间的关系上,那么我可以通过派生模板本身使它们全部成为“某种”基础:

template <size_t N>
class Unsigned : private UnsignedCommon { ...

...但我将这种方法搁置一旁,因为,好吧,人们不会那个(使所有的东西都成为“一种”)内置插件,加上案例如果我没记错的话,确实实际上将它们视为一个公共(public)类,它需要初始化静态、返回指针并让客户端自行销毁。那么第二个问题:我过早放弃这个替代方案是不是做错了?

最佳答案

简而言之,您的问题与内置整数类型的问题没有什么不同。给出 short ,您不能在其中存储大整数。你不能在运行时决定使用哪种类型的整数,除非你使用 switch或类似于在几个预定义选项之间进行选择(例如,shortintlonglong long。或者在您的情况下,Unsigned<4>Unsigned<8>Unsigned<256>。无法计算大小在运行时动态地以任何方式。

您必须定义动态大小的类型(类似于 std::vector ),其中大小不是模板参数,以便单个类型可以存储任何 整数类型(然后接受暗示的效率损失),或者接受必须在编译时选择大小,并且处理“任意”整数的唯一选择是硬编码一组预定义的大小和在运行时在它们之间进行选择。

decltype也不会解决你的问题。它与 auto 非常相似,它完全在编译时工作,并且只返回表达式的类型。 (2+2 的类型是 int,编译器在编译时知道这一点,即使值 4 仅在运行时计算)

关于c++ - 模板:在运行时从(并引用)非类型参数实例化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3453751/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com