C++ c++;20如何制作一个只包含允许的类型和自身实例的受约束元组式容器
假设我想制作一个类似元组的模板容器作为api接口的一部分。我想把它限制在允许的类型列表和这个模板容器的一个实例中。现在我有这样的东西:C++ c++;20如何制作一个只包含允许的类型和自身实例的受约束元组式容器,c++,c++20,c++-concepts,C++,C++20,C++ Concepts,假设我想制作一个类似元组的模板容器作为api接口的一部分。我想把它限制在允许的类型列表和这个模板容器的一个实例中。现在我有这样的东西: #include <string> #include <tuple> #include <utility> #include <type_traits> template<typename T> constexpr const bool bIsAllowedType = std::is_sam
#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;
}
我希望它尽可能简单,因此请尽可能使用第三方libs(如Boost)您可以使用部分模板专门化来检查这一点
template <typename T>
constexpr const bool bIsContainerType = false;
template <typename... Types>
constexpr const bool bIsContainerType<Container<Types...>> = true;
由于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;
}
#包括
#包括
#包括
#包括
模板
结构双允许型;
模板
constexpr const bool bIsAllowedArgList=
(biAllowedType::value&&…);
模板
概念英语=
bIsAllowedArgList对我来说,甚至第一个代码都不会使用g++-std=c++2a…
编译,只使用main
中的两行中的任何一行。不相关的评论:如果你选择remove\u reference\t
,为什么不选择?1all
可能不起作用。gcc11将其视为另一种类型的int64_t{1}
刚刚使用Visual Studio 2019在启用实验功能的情况下编译了它。如果我和Martin Morterol的效果一样,这正是我想要的,如果我继续使用“Container(1LL,2.0,std::string(“three”),”你的\\OK
行无法生成
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>;
#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;
}