Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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

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_Default_Enable If_Conditional Types - Fatal编程技术网

C++ 模板类默认类型和条件

C++ 模板类默认类型和条件,c++,templates,default,enable-if,conditional-types,C++,Templates,Default,Enable If,Conditional Types,我想对MyClass使用std::enable_if以便只接受(uint32_t | uint64_t),同时如果用户没有提供任何类型;根据以下条件选择默认值 但我不能让它工作。(C++17) #包括 #包括 模板 类MyClass { 私人: std::向量vs; 公众: // ... }; int main(){ MyClass a;//好的,defaut类型使用uint32\u t或uint64\u t MyClass b;//好的,使用用户提供的类型 MyClass c;//不能编译,T

我想对MyClass使用std::enable_if以便只接受(uint32_t | uint64_t),同时如果用户没有提供任何类型;根据以下条件选择默认值

但我不能让它工作。(C++17)

#包括
#包括
模板
类MyClass
{
私人:
std::向量vs;
公众:
// ...
};
int main(){
MyClass a;//好的,defaut类型使用uint32\u t或uint64\u t
MyClass b;//好的,使用用户提供的类型
MyClass c;//不能编译,T不是uint32\u T、uint64\u T中的一个
}
您可以添加以执行检查

template <typename T=std::conditional_t<sizeof(void*) == 8, std::uint64_t, std::uint32_t>>
class MyClass
{
  static_assert(std::is_same_v<T, std::uint64_t> || std::is_same_v<T, std::uint32_t>, "T must be std::uint64_t or std::uint32_t");
  private:
    std::vector<T> vs;
  public:
  // ...
};
模板
类MyClass
{
静态断言(std::is_same_v | std::is_same_v,“T必须是std::uint64或std::uint32_T”);
私人:
std::向量vs;
公众:
// ...
};

宋彦尧用
静态断言提出的解决方案是好的、完全有效的,并且比我下面建议的要短。然而

建议另一种选择,让编译器在不需要
静态断言的情况下检查您:

template <typename T>
class MyClassBase {
    std::vector<T> vs;
  public:
  // ...
};

template <typename T =
            std::conditional_t<sizeof(void*) == 8, std::uint64_t, std::uint32_t>>
class MyClass;

template <>
class MyClass<std::uint64_t>: public MyClassBase<std::uint64_t> {};

template <>
class MyClass<std::uint32_t>: public MyClassBase<std::uint32_t> {};
模板
类MyClassBase{
std::向量vs;
公众:
// ...
};
模板
类MyClass;
模板
类MyClass:公共MyClassBase{};
模板
类MyClass:公共MyClassBase{};

若指针的大小较小,您会怎么做?承认,它们很罕见,但仍然有一些16位µC存在。。。(当然,uint32\u t也适用于这些测试)。我个人更喜欢测试
sizeof(void*)==sizeof(uint64\u t)
。承认,同样罕见,但即使在今天,一些专门的机器仍有
CHAR\u BIT==16
…限制字体宽度的真正原因是什么?也许像
std::is_integral&&std::is_unsigned
这样的东西更可取
std::uintptr\u t
可能是一个很好的默认值,用户甚至可以在系统/编译器上使用一个128位无符号整数,提供一个……如果出于任何原因都没有可用的
static\u assert
,这很好。好的,
std::conditional
可能也不是,但这很容易单独实现。缺点:一个必须维护两个实现。@Aconcagua
static\u assert
意味着可以创建类型,但我们通过代码中的某个地方禁止它。假设其他编译单元的某个人添加了显式专门化
模板类MyClass{}。人们可能会认为,
静态断言
禁止它,但事实并非如此。在我的方法中,类型根本不存在,除非您创建它。没有魔法。但是,这两种方法都是有效的。有效的区别是什么?两种方法都只允许将模板用于所需的两种类型,并且两种方法都允许通过添加另一种专门化来规避(所需!)限制。我很清楚背后的技术差异,但这不是我的观点——相反,当被迫为C++03或更高版本编译时,您也可以使用您的方法,而另一种方法则不能。即使在C++11使用了近十年之后的今天,这种限制仍然存在。。。
template <typename T>
class MyClassBase {
    std::vector<T> vs;
  public:
  // ...
};

template <typename T =
            std::conditional_t<sizeof(void*) == 8, std::uint64_t, std::uint32_t>>
class MyClass;

template <>
class MyClass<std::uint64_t>: public MyClassBase<std::uint64_t> {};

template <>
class MyClass<std::uint32_t>: public MyClassBase<std::uint32_t> {};