Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ 将std::type_标识对象转换为类型_C++_C++20_Typetraits - Fatal编程技术网

C++ 将std::type_标识对象转换为类型

C++ 将std::type_标识对象转换为类型,c++,c++20,typetraits,C++,C++20,Typetraits,假设我们创建了两个type_的函数,它们返回std::type_标识,: 有没有一种方法可以免除上述表达式中对decltype的需要,或者将其放入可重用表达式中,以实现更好的效果,如: // can this work? type_of<int>()::type i1; type_of<int{}>()::type i2; //这行吗? ()的类型:类型i1; ()的类型:类型i2; 或者更好: // can this work?? type_of_t<int&

假设我们创建了两个
type_的
函数,它们返回
std::type_标识
,:

有没有一种方法可以免除上述表达式中对
decltype
的需要,或者将其放入可重用表达式中,以实现更好的效果,如:

// can this work?
type_of<int>()::type i1;
type_of<int{}>()::type i2;
//这行吗?
()的类型:类型i1;
()的类型:类型i2;
或者更好:

// can this work??
type_of_t<int> i1;
type_of_t<int{}> i2;
//这能行吗??
_t i1的类型_;
_t i2的类型_;

注意:类型和非类型模板参数的专门化(可能是一个方向)不起作用(无法编译):

模板
结构类型_;
模板

{/的结构类型_可以创建类型别名。但是不能“重载”它。因此我的解决方案是创建两个:

template <auto Var>
using type_of_var_t = decltype(type_of<Var>())::type;

template <class T>
using type_of_t = decltype(type_of<T>())::type;

auto test()
{
    type_of_var_t<11> i1 = 24;
    type_of_t<int> i2 = 17;

}
模板
使用类型为的=decltype(类型为())::type;
模板
使用type of t=decltype(type of())::type;
自动测试()
{
i1的类型=24;
类型_的_t i2=17;
}

std::type\u标识获取类型
对象:


通过以下方式从
std::type\u identity
创建类型的一般情况:

template<auto VAR>
constexpr auto type_of() {
    return std::type_identity<decltype(VAR)>{};
}

template<typename T>
constexpr auto type_of() {
    return std::type_identity<T>{};
}

template<typename T, typename... Args>
auto create(std::type_identity<T>, Args&&... args) {
    return T{std::forward<Args>(args)...};
}

auto i1 = create(type_of<int>(), 7);
auto i2 = create(type_of<int{}>(), 7);

<代码>模板< /p> C++中,模板参数必须是一个值、一个类型或另一个模板(它本身必须适合于声明的模板头)。它必须是其中的一个。

如果要执行此操作,请执行以下操作:

其思想是获取调用方不知道模板参数是类型还是变量的内容

能够做到这一点的基本要求是编写一个带有参数(可以是值或类型)的模板

<>这不是C++允许的事情。< /P> 模板函数重载允许您避免类似的情况。但这只起作用,因为它不是一个模板。重载的是两个模板。选择哪一个模板取决于提供的模板参数

模板类不能重载。模板专门化不能更改原始模板的性质(如其模板参数)。它只能允许您重新解释原始模板参数的模板参数,以便提供替代实现


如果你想要这个,你必须等待,或者C++得到模板参数,它可以是任何东西,或者直到C++获得将类型转换为值和返回(即:反射)的能力。

< P>设计中,C++模板中的模板参数可以是模板、类型或值。 在模板中,您知道它们是什么。模板中依赖于模板参数的所有表达式都使用
typename
template
关键字(或上下文)消除歧义,以便在替换参数之前知道它们的类别

现在有了元编程库,可以用值替代所有3个

template<class T> struct type_tag_t {using type=T;};
template<class T> constexpr type_tag_t<T> tag={};
template<template<class...>class Z> struct template_z_t {
  template<class...Ts>
  using result = Z<Ts...>;
  template<class...Ts>
  constexpr result<Ts...> operator()( type_tag_t<Ts>... ) const { return {}; }
};
template<template<class...>class Z>
constexpr template_z_t<Z> template_z = {};
所以

constexpr auto vector_z=template_z;
constexpr auto vector_tag=vector_z(tag,tag);
然后您可以返回到类型:

type<vector_tag> v{1,2,3,4};
v型{1,2,3,4};

这可能不是您想要的。

您想要实现什么?如果您知道
t
是一种类型,只需使用
ti1
创建该类型的变量。如果您知道
t
是一种变量,只需使用
decltype(t)i2
创建相同类型的变量。
函数的
type\u可以返回任何类型。
type\u的实现只是一个最简单的例子。像您这样使用type\u标识有0点意义。只需对您尝试传输的类型使用一个类型别名。为什么要在实际传输时传递int的type\u标识LY想要通过int类型?对我来说没有意义。换句话说:如果不需要的话,不要使用任何东西。很多C++库是“按需按需”。只有当你明确需要时才可以使用。这里我看不出有什么需要。它就像一个阅读设计模式并试图为每一个事物选择一个和一个企业混乱结果的人。如果你想返回一个类型,为什么你使用定义定义的函数返回对象?C++中的类型是从什么返回的?挂载到元函数时,会出现阻抗不匹配,正如您所看到的,type_identity和类似的解决方案无法解决这一问题。考虑到语言的现状,这不是一个可解决的问题,直到类型成为一级值。一旦语言允许返回类型作为值,然后在需要类型的任何地方使用这些值,t这个问题将得到解决。到目前为止,只有元函数的使用点负担会更少,因为它们本身就是类型。您是否在寻找类似的东西?当然,但想法是获取一些调用方不知道模板参数是类型还是变量的东西,主要是为了便于使用。这如何解决问题问题?你写的问题是关于获取值的类型,而不是基于该类型创建对象。@Nicolas更新了答案,以更优雅的方式获取类型。
template<auto x>
using type = typename decltype(x)::type;
decltype(type_of<int>())::type i1;
decltype(type_of<int{}>())::type i2;
type<type_of<int>()> i1;
type<type_of<int{}>()> i2;
template<auto VAR, typename... Args>
auto create_type_of(Args&&... args) {
    return decltype(VAR){std::forward<Args>(args)...};
}

template<typename T, typename... Args>
auto create_type_of(Args&&... args) {
    return T{std::forward<Args>(args)...};
}

auto i1 = create_type_of<int>(7);
auto i2 = create_type_of<int{}>(7);
template<auto VAR>
constexpr auto type_of() {
    return std::type_identity<decltype(VAR)>{};
}

template<typename T>
constexpr auto type_of() {
    return std::type_identity<T>{};
}

template<typename T, typename... Args>
auto create(std::type_identity<T>, Args&&... args) {
    return T{std::forward<Args>(args)...};
}

auto i1 = create(type_of<int>(), 7);
auto i2 = create(type_of<int{}>(), 7);
template<class T> struct type_tag_t {using type=T;};
template<class T> constexpr type_tag_t<T> tag={};
template<template<class...>class Z> struct template_z_t {
  template<class...Ts>
  using result = Z<Ts...>;
  template<class...Ts>
  constexpr result<Ts...> operator()( type_tag_t<Ts>... ) const { return {}; }
};
template<template<class...>class Z>
constexpr template_z_t<Z> template_z = {};
template<auto x>
using type = typename decltype(x)::type;

template<auto x>
constexpr std::integral_constant<std::decay_t<decltype(x)>, x> k = {};
constexpr auto vector_z = template_z<std::vector>;
constexpr auto vector_tag = vector_z( tag<int>, tag<std::allocator<int>> );
type<vector_tag> v{1,2,3,4};