【发布时间】:2026-02-06 07:50:01
【问题描述】:
我有一个类模板,它有两个构造函数,一个采用无符号类型,另一个采用自身的常量引用,两个构造函数在构造类的方式上具有相同的行为。
如何构造这个类有 3 种情况,这取决于它的类型的大小和传入的类型。我还希望通过类构造函数的初始化列表来初始化成员。
这个类看起来像这样:
template<typename T>
struct Foo {
T data;
template<typename P>
Foo( const P val, const unsigned char c ) :
data { static_cast<T>( val /* some operation done to val based on each case*/ ) } {
assert( /* based on cases above,
and each case has its own conditions to assert */ );
}
template<typename P>
Foo( const Foo<P>& f, const unsigned char c ) :
data{ static_cast<T>( Foo.val /* some operation done to val based on each case*/ ) } {
assert( /* based on cases above,
and each case has its own conditions to assert */ );
};
这3种情况如下:
case 1: if( sizeof(P) > sizeof(T) ) construct Foo<T> with these conditions, initialize member data in this specific way and assert accordingly case 2: if( sizeof(T) > sizeof(P) ) construct Foo<T> with these conditions, initialize member data in this specific way and assert accordingly case 3: if ( sizeof(T) == sizeof(P) ) construct Foo<T> with these conditions, initialize member data in this specific way and assert accordingly
有没有简单的方法来做到这一点?请记住,成员正在通过构造函数的初始化列表进行初始化,但数据成员将以不同的方式初始化,这取决于上述 3 种情况。
我不知道我该如何解决这个问题。这里的所有信息都应该在编译时可用,所以我不明白为什么会有问题,但我不知道如何设置构造函数来获得这个功能。此外,这甚至可以做到吗?
编辑
T 和 P 类型的一些背景知识:T 和 P 都是以下任何一种:
类型:以字节为单位的大小:以位为单位的大小:
std::uint8_t1字节8位std::uint16_t2 字节 16 位std::uint32_t4 字节 32 位std::uint64_t8 字节 64 位
一旦我们根据两个大小的比较定义了 3 个条件,断言的工作方式如下:传入的 unsigned char 也是断言中条件的一部分,并且它有一个可以使用的值范围是。这是一个表格:我将用idx 表示的无符号字符。
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
if ( sizeof(P) > sizeof(T) )
// comparision formula:
// idx <= (((sizeof(P) / sizeof(T)) - 1)
// Foo<T = u8> From: Foo<P = u16> idx[0,1], Foo<P =u32> idx[0,3], Foo<P = u64> idx[0,7]
// Foo<T = u16> From: Foo<P = u32> idx[0,1], Foo<P = u64> idx[0,3]
// Foo<T = u32> From: Foo<P = u64> idx[0,1]
if ( sizeof(T) > sizeof(P) )
// comparision formula:
// idx <= (((sizeof(T) / sizeof(P)) - 1)
// Foo<T = u16> From: Foo<P = u8> idx[0,1]
// Foo<T = u32> From: Foo<P = u8> idx[0,4], Foo<P = u16> idx[0,1]
// Foo<T = u64> From: Foo<P = u8> idx[0,7], Foo<P = u16> idx[0,3], Foo<P = u32> idx[0,1]
if ( sizeof(P) == sizeof(T) ) {
// no conditional checks
// no assertion
// in this case idx is not used and is not a part of any calculation
// the two sizes match so it's just a normal initialization.
【问题讨论】:
标签: c++ templates constructor c++17 list-initialization