模板 class 默认类型和条件
template class default type and condition
我想对 MyClass 使用 std::enable_if 以便只接受 (uint32_t | uint64_t),同时如果用户没有提供任何类型;根据以下条件选择默认的。
但我无法让它工作。 (C++17)
#include <vector>
#include <cstdint>
template <typename T=std::conditional_t<sizeof(void*) == 8, std::uint64_t, std::uint32_t>>
class MyClass
{
private:
std::vector<T> vs;
public:
// ...
};
int main(){
MyClass a; // OK, the defaut type is used either uint32_t or uint64_t
MyClass<std::uint32_t> b; // Ok, use the user provided type
MyClass<long> c; // must not compile, T is not one of uint32_t, uint64_t
}
您可以添加 static_assert
来执行检查。
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:
// ...
};
songyanyao 和 static_assert
提出的解决方案很好,完全有效并且比我在下面建议的更短。然而...
建议另一种选择,让编译器检查你而不需要 static_assert
:
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> {};
我想对 MyClass 使用 std::enable_if 以便只接受 (uint32_t | uint64_t),同时如果用户没有提供任何类型;根据以下条件选择默认的。
但我无法让它工作。 (C++17)
#include <vector>
#include <cstdint>
template <typename T=std::conditional_t<sizeof(void*) == 8, std::uint64_t, std::uint32_t>>
class MyClass
{
private:
std::vector<T> vs;
public:
// ...
};
int main(){
MyClass a; // OK, the defaut type is used either uint32_t or uint64_t
MyClass<std::uint32_t> b; // Ok, use the user provided type
MyClass<long> c; // must not compile, T is not one of uint32_t, uint64_t
}
您可以添加 static_assert
来执行检查。
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:
// ...
};
songyanyao 和 static_assert
提出的解决方案很好,完全有效并且比我在下面建议的更短。然而...
建议另一种选择,让编译器检查你而不需要 static_assert
:
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> {};