Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ C++;模板函数类型推导_C++_Templates_C++11 - Fatal编程技术网

C++ C++;模板函数类型推导

C++ C++;模板函数类型推导,c++,templates,c++11,C++,Templates,C++11,我有以下代码: template <typename T, void (*f)(T*)> class callfn { public: void operator()(T* obj) const { f(obj); } }; void call(int* foo) {} void test() { callfn<int, call> fun; fun(1); } 而不是修改 >调用< /代码>,可以安排 Calfn < /Cube模板

我有以下代码:

template <typename T, void (*f)(T*)>
class callfn
{
  public:
  void operator()(T* obj) const
  {
    f(obj);
  }
};

void call(int* foo) {}

void test()
{
  callfn<int, call> fun;
  fun(1);
}

而不是修改<代码> >调用< /代码>,可以安排<代码> Calfn < /Cube模板/模板,这样它可以从<代码> f>代码>类型>

< p>推断不需要知道结构或类的ARG,只有函数在C++中有模板类型演绎。p> 报纸似乎解决了这个问题,所以你似乎不是唯一一个觉得这很烦人的人(我也是)。我不知道它是否会被包括在内,但这篇论文至少意味着其他人正在考虑它。将能够消除非类型模板参数的冗余typename

另一件事(也是在c++14中)是下一个标准中会用到的。自己编写代码也可能相对容易

正如我在评论中提到的,不清楚你到底想用这个实现什么,如果不得不写额外的类型实际上是一个障碍的话

由于您在评论中明确表示,您需要使用此选项来为
唯一\u ptr
创建一个删除器,因此我不确定该删除器出了什么问题

std::unique_ptr<int,void(*)(int*)> ptr(int_ptr,deleter);
std::unique_ptr ptr(int_ptr,deleter);
在的顶部添加。虽然不能单独使用模板类,但使用一些帮助程序(包括宏)可以:

template <typename T>
T deduce(void(*)(T*));

#define CALLFN(f) callfn<decltype(deduce(f)), f> 
正如OP评论中所说,我们通常

std::unique_ptr<MObj, void(*)(MObj*)> p1(nullptr, mfree);
assert(sizeof(p1) == sizeof(MObj*) * 2);
我相信上述解决方案唯一的麻烦是需要键入
callfn
MObj
两次。那么,这个呢:

template <typename T, void (*f)(T*)>
using light_unique_ptr = std::unique_ptr<T, callfn<T, f>>;

light_unique_ptr<MObj, mfree> p3; // 1
assert(sizeof(p3) == sizeof(MObj*));
模板
使用灯光_unique_ptr=std::unique_ptr;
灯光_独特_ptr p3;//1.
断言(sizeof(p3)=sizeof(MObj*);
我也明白(也许我错了)我的意图是做一些更短的事情,比如

lighter_unique_ptr<mfree> p4; // 2
assert(sizeof(p4) == sizeof(MObj*));
lighter\u unique\u ptr p4;//2.
断言(sizeof(p4)=sizeof(MObj*);
并让编译器从
mfree
推断指向对象的类型。正如我所指出的,这可以通过宏实现,但我认为这不是一件好事,原因有二:

  • 如果我们对
    mfree
    有不同的重载(比如
    voidmfree(MObj*)
    voidmfree(Foo*)
    ),则它不起作用
  • 用户通常希望在其实例化和(最终)删除程序中看到
    std::unique_ptr
    的指向类型。上面的第1行确实显示了类型(
    MObj
    ),但第2行没有显示。看不到类型可能会让一些人感到困惑

  • 我同意上面第二点是有争议的(类似于“我应该使用自动”的辩论)。

    你到底在做什么?RN它只是生成了一个本质上与函数本身相同的函子,目标是将它用作类型的删除函数,以便我可以作为删除函数传入函数,而不需要实际传入函数的4字节开销*为什么这不会有任何开销,如果一个函子会有更高的开销,我只会使用fp,还有std::函数有什么问题,如果你反对fp'ssory,让我试着澄清一下<代码>无效mfree(MObj*o);std::unique_ptr此操作的目标不仅是生成一个删除器,而且是一个不会占用每个指针任何额外空间的删除器,就像
    default_deleter
    那样,但支持任意函数。@Arelius只需使用decltype,我将添加一个带有that@Arelius事实上,这真的没有多大帮助,所以你已经有了你的解决方案,但你只想少输入5个字母,这是它的要点吗?正确,5个,或更多或更少取决于标识符的长度。看起来这是不可能的,但实际上在我认为这似乎是一个更适用的文件中解决。我喜欢这个解决方案,我最终可能不会仅仅为了避免宏而使用它。但这确实是一个非常聪明的解决方案。难道你不能在
    调用fn
    中将
    推断
    定义为私有类静态函数,将成员类型别名设置为
    decltype(推断(f))
    ,并使用(指向)该类型的指针作为
    操作符()的输入吗?(您可以使用“
    template
    ”作为
    callfn
    的标题,查看
    f
    在调用
    推断
    时是否无法匹配)@CTMacUser我不确定是否正确理解您的意思,但在我看来,这似乎不起作用。如果我们有
    template类callfn
    ,那么
    callfn
    将需要实例化一个类型。但是,deleter,比如说
    mfree
    ,是某种类型的函数,但它本身不是一种类型。因此,
    callfn
    无法编译。@Cassineri,是的,我刚刚试过
    f
    是一个值(函数指针)而不是类型。因此,我们必须用实际的函数类型替换“
    typename
    ”,但我们不能,因为我们希望它是可变的。除了像
    CALLFN
    这样的宏之外,我们无法绕过两个模板参数。
    std::unique_ptr<MObj, void(*)(MObj*)> p1(nullptr, mfree);
    assert(sizeof(p1) == sizeof(MObj*) * 2);
    
    std::unique_ptr<MObj, callfn<MObj, mfree>> p2;
    assert(sizeof(p2) == sizeof(MObj*));
    
    template <typename T, void (*f)(T*)>
    using light_unique_ptr = std::unique_ptr<T, callfn<T, f>>;
    
    light_unique_ptr<MObj, mfree> p3; // 1
    assert(sizeof(p3) == sizeof(MObj*));
    
    lighter_unique_ptr<mfree> p4; // 2
    assert(sizeof(p4) == sizeof(MObj*));