c++ - c ++ 20如何制作一个像容器一样的约束元组,它只包含允许的类型和自身的一个实例
问题描述
想象一下,我想制作一个像模板容器一样的元组作为 api 接口的一部分。我想将其限制为允许的类型列表以及此模板容器的实例。现在我有这样的事情:
#include <string>
#include <tuple>
#include <utility>
#include <type_traits>
template<typename T>
constexpr const bool bIsAllowedType =
std::is_same<T, bool>::value ||
std::is_same<T, void*>::value ||
std::is_same<T, double>::value ||
std::is_same<T, int64_t>::value ||
std::is_same<T, std::string>::value;
template<typename T, typename... Args>
constexpr const bool bIsAllowedArgList =
bIsAllowedType<std::remove_reference_t<T>> &&
bIsAllowedArgList<Args...>;
template<typename T>
constexpr const bool bIsAllowedArgList<T> =
bIsAllowedType<std::remove_reference_t<T>>;
template<typename... Args>
concept CAllowedArgList =
bIsAllowedArgList<Args...>;
template<CAllowedArgList... Args>
class Container
{
private:
using TupleT = std::tuple<std::decay_t<Args>...>;
TupleT data;
public:
Container() = default;
Container(Args&&... args) : data(std::forward<Args>(args)...) {}
};
int main()
{
auto test_cont = Container(1LL, 2.0, std::string("three")); // Ok
auto err_cont = Container(std::wstring(L"wide string")); // Not ok, type's not allowed
return 0;
}
那么,我如何让它也接受它自己的一个实例呢?像这样:
int main()
{
auto test_cont = Container(1LL, Container(2.0, std::string("three")));
return 0;
}
我希望它尽可能简单,所以请尽可能限制使用第三方库(如 Boost)
解决方案
您可以使用部分模板专业化来检查这一点。
template <typename T>
constexpr const bool bIsContainerType = false;
template <typename... Types>
constexpr const bool bIsContainerType<Container<Types...>> = true;
然后我们只需将其添加到您的签到列表中bIsAllowedType
template<typename T>
constexpr const bool bIsAllowedType =
std::is_same<T, bool>::value ||
std::is_same<T, void*>::value ||
std::is_same<T, double>::value ||
std::is_same<T, int64_t>::value ||
std::is_same<T, std::string>::value ||
bIsContainerType<T>;
由于bIsAllowedType
现在需要知道Container
哪些需要了解我们的概念,因此我将其更改bIsAllowedType
为结构,以便我们可以转发声明它。
#include <string>
#include <tuple>
#include <utility>
#include <type_traits>
template<typename T>
struct bIsAllowedType;
template<typename... T>
constexpr const bool bIsAllowedArgList =
(bIsAllowedType<std::remove_reference_t<T>>::value && ...);
template<typename... Args>
concept CAllowedArgList =
bIsAllowedArgList<Args...>;
template<CAllowedArgList... Args>
class Container
{
private:
using TupleT = std::tuple<std::decay_t<Args>...>;
TupleT data;
public:
Container() = default;
Container(Args&&... args) : data(std::forward<Args>(args)...) {}
};
template <typename T>
constexpr const bool bIsContainerType = false;
template <typename... Types>
constexpr const bool bIsContainerType<Container<Types...>> = true;
template<typename T>
struct bIsAllowedType {
static constexpr bool value =
std::is_same<T, bool>::value ||
std::is_same<T, void*>::value ||
std::is_same<T, double>::value ||
std::is_same<T, int64_t>::value ||
std::is_same<T, std::string>::value ||
bIsContainerType<T>;
};
int main()
{
auto test_cont = Container(static_cast<int64_t>(1), 2.0, std::string("three")); // Ok
//auto err_cont = Container(std::wstring(L"wide string")); // Not ok, type's not allowed
auto test_cont2 = Container(static_cast<int64_t>(1), Container(2.0, std::string("three")));
return 0;
}
现场演示
推荐阅读
- xamarin.forms - 如何在 xamarin 表单的工具栏项中添加字体图标
- php - 为什么 JSON 值不显示在 PHP 中?
- python - 成功运行任务但不跳过
- python - 我收到“RequestsDependencyWarning:urllib3 (1.25.3) 或 chardet (3.0.4) 与支持的版本不匹配!”
- asp.net-core - Blazor:如何从子组件中的事件中获取发件人
- flutter - 如何从类字段设置提供者值?
- parallel-processing - 如何在 Vulkan 中适当地设置工作组计数
- ansible - 无法使用循环复制文件
- regex - 修剪标签之间的空间
- sql - 如何比较jsonb列的数组元素