Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 初始化类模板';根据不同的条件选择不同的成员_C++_Templates_Constructor_C++17_List Initialization - Fatal编程技术网

C++ 初始化类模板';根据不同的条件选择不同的成员

C++ 初始化类模板';根据不同的条件选择不同的成员,c++,templates,constructor,c++17,list-initialization,C++,Templates,Constructor,C++17,List Initialization,我有一个类模板,它有两个构造函数,一个采用无符号类型,另一个采用自身的常量引用,两个构造函数在构造类时具有相同的行为 关于如何构造此类,有3种情况,这取决于类型的大小和传入的类型。我还希望通过类构造函数的初始值设定项列表初始化成员 这个类看起来像这样: template<typename T> struct Foo { T data; template<typename P> Foo( const P val, const unsigned ch

我有一个类模板,它有两个构造函数,一个采用无符号类型,另一个采用自身的常量引用,两个构造函数在构造类时具有相同的行为

关于如何构造此类,有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 */ );
};

在这种情况下,如果不能使用constexpr,则必须使用SFINAE。首先,将构造从
Foo

构造函数委托给
P
构造函数:

template<typename P>
Foo(const Foo<P>& f, const unsigned char c) : Foo(f.val, c) {}

如果您希望
p
构造函数具有相同的断言,而不管
p
的大小,您也可以添加额外的委托层。我将编辑上面关于断言如何工作的问题。我完成了编辑,以提供有关如何执行构造的更多信息。不过,我想我已经开始了解或查看SFINAE的模式,以及如何使用
std::enable_(如果_t
)。我创建了一个虚拟类来复制您在上面所做的操作,我收到了Visual Studio 2017编译器错误C2059:语法错误:
sizeof
我想我现在已经完成了这个shell,我还没有做任何测试。有一次,我在一个简单的案例中测试了这一点;我应该能够把它融入我的实际课堂。
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.
template<typename P>
Foo(const Foo<P>& f, const unsigned char c) : Foo(f.val, c) {}
template<typename P, std::enable_if_t<(sizeof(P) > sizeof(T))>* = nullptr>
Foo(P val, const unsigned char c) : data(...) {}

template<typename P, std::enable_if_t<sizeof(P) == sizeof(T)>* = nullptr>
Foo(P val, const unsigned char c) : data(...) {}

template<typename P, std::enable_if_t<(sizeof(P) < sizeof(T))>* = nullptr>
Foo(P val, const unsigned char c) : data(...) {}