C++ C++;:模板类型的提取

C++ C++;:模板类型的提取,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,我正在开发一个编译时包装库,偶然发现了一个从给定类型中提取模板参数类型的问题 情况如下。我有一个不可更改的类R: 模板 类R{}; 我还有一个不可更改的main功能: intmain() { 自动r=新r(); //知道“r”类型的函数 创建_obj(); 删除r; 返回0; } create_obj函数就是我正在使用的函数。出于可视化目的,我将按以下方式编写: 模板 void create_obj() { //打印函数的类型(输出:R*) 标准::cout void create_obj(

我正在开发一个编译时包装库,偶然发现了一个从给定类型中提取模板参数类型的问题

情况如下。我有一个不可更改的类
R

模板
类R{};
我还有一个不可更改的
main
功能:

intmain()
{
自动r=新r();
//知道“r”类型的函数
创建_obj();
删除r;
返回0;
}
create_obj
函数就是我正在使用的函数。出于可视化目的,我将按以下方式编写:

模板
void create_obj()
{
//打印函数的类型(输出:R*)
标准::cout
void create_obj()
{
//打印函数的类型(输出:int)

std::cout是的,这是可能的,一种方法:

模板
类R{};
模板
结构提取_impl{};
模板
结构提取\u impl{
使用类型=T;
};
模板
使用extracted_type=typename extract_impl::type;
模板
void create_obj()
{
静态断言(std::is_same_v);
}
int main()
{
创建_obj();
}

约定是,
R
本身将通过
使用
公开类型,但您写道它是不可更改的。

我通过
R
类型调用
create\u obj()

create_obj<decltype(r)>();
但是如果希望调用
create_obj()
只传递类型
R
(或指向
R
)而不实例化类型
R
的对象,则可以定义轻量级类型包装器

template <typename>
struct typeWrapper
 { /* empty! */ };
并使用
decltype(r)

并且仅定义基于
R*
指针的专门化,其中包含
静态
func()
方法

template <typename T>
struct create_obj<R<T> *>
 {
   static void func ()
    { /* do something with T */ } 
 };
或通过
R*

create_obj::func();

如果您愿意,可以在
create_obj()
中插入一个普通(非
static
)方法,而不是
func()
方法;可能是一个
操作符()
。但是,通过这种方式,您必须实例化一个
create_obj
对象来调用该方法。

是否
create_obj
实际上应该引用
r
或其他什么?目前它不带任何参数,也不返回任何内容,因此您希望它做什么并不完全清楚。这是您想要的吗?@NathanOliver I我们已经尝试了
std::declval
,但是这里显示为class
R
的指定类型
C
可能是一个非常复杂的类,无法轻松实例化。@无用这正是没有引用、没有对象、无法创建任何内容的要点。我们的想法只是从一个已经存在的类中提取一个类型现有的类型。这是一个非常有趣的解决方案……我从未想过在 StuttStudio中明确指定类<代码> R<代码>。非常感谢,我正在考虑一个正确的解决方案。@尤金科列斯尼科夫:你是对的,错过了。它也没有考虑引用或指针。我把它编辑得稍微干净些。tra
使用
也消除了对
typename
的需要。
template <typename T>
void create_obj (typeWrapper<R<T> *> const &)
 { /* do something with T */ }
create_obj(typeWrapper<decltype(r)>{});
create_obj(typeWrapper<R<int> *>{});
template <typename>
struct create_obj;
template <typename T>
struct create_obj<R<T> *>
 {
   static void func ()
    { /* do something with T */ } 
 };
create_obj<decltype(r)>::func();
create_obj<R<int> *>::func();