本文介绍了如何修复模板中的错误重构decltype的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 修改可能无法完成,参见函数模板的函数指针的清理实现尽管答案1有一个C宏解决方法 https://stackoverflow.com/a/18706623/2332068 我将一个函数传入一个成为构造函数预先提供的参数的模板,但也需要在该函数上使用 decltype 来将函数类型传递给 unique_ptr< ;. ..> template instantiator(?是那个正确的单词) 如果我预先使用 decltype 作为一个额外的模板参数,但不是如果我在作为参数传递的函数模板内调用它。 我使用g ++ 4.9.2,并在这里扩展我的探索调用子类的unique_ptr继承模板的构造,我继承的unique_ptr 有我发现一些析构函数不会返回 void ,所以我想要一个更通用的模板,它不需要指定析构函数类型。 我现在的代码是: pre $ void free_int(int * p){删除p; } 模板< typename T,void(* D)(T *)> class unique_dptr:public std :: unique_ptr< T,decltype(D)> { public:unique_dptr(T * t):std :: unique_ptr< T,decltype(D)>(t,D){}; }; 使用int_ptr = unique_dptr< int,:: free_int>; int_ptr i(new int(2)); 但请注意 void(* D)(T *)调用签名以将析构函数限制为一个void函数,该函数将指针指向 T 以这种形式使用的的unique_ptr : 的unique_ptr< FOO,decltype( &安培; :: free_foo)GT; 我想要这样的东西: 模板< typename T,typename D> class unique_gptr:public std :: unique_ptr< T,decltype(& D)> { public:unique_gptr(T * t):std :: unique_ptr< T,decltype(& D)>(t,D){}; }; 使用int_gptr = unique_gptr< int,:: free_int>; int_gptr ig(new int(2)); 但编译器讨厌它: error:template argument 2 is invalid class unique_gptr:public std :: unique_ptr< T,decltype(& D)> { ^ 毫无疑问,古老的C-macro风格的标记粘贴是我错误的瞄准 我试着从 decltype(& D)中删除& 但会导致错误: error:decltype的参数必须是表达式 然而,这是正常的: 模板<类型名称T,类型名称D,D F> class unique_gptr:public std :: unique_ptr< T,D> { public:unique_gptr(T * t):std :: unique_ptr< T,D>(t,F){}; }; 使用int_gptr = unique_gptr< int,decltype(& :: free_int),:: free_int>; int_gptr ig(new int(2)); 但我想知道我做错了,我无法管理移动 decltype(& :: free_int)。 其他解决方案 我意识到我可以为其他固定的自由函数类型编写额外的特化,替换 void(*)(void *) 我知道我可以覆盖我的类型的 std :: default_delete 。 但是这实际上是模板构成中的一个练习 解决方案我认为c ++ $ b 模板< typename T,typename D> class unique_gptr:public std :: unique_ptr< T,decltype(& D)> { public:unique_gptr(T * t):std :: unique_ptr< T,decltype(& D)>(t,D){}; }; 使用int_gptr = unique_gptr< int,:: free_int>; int_gptr ig(new int(2)); 注意 decltype 应用于 D ,它被声明为 typename 。所以 D 是一种类型。但是 decltype 不能用在类型上。 首先,代码尝试得到一个类型的地址(& )。其次, decltype 的参数预期为表达式,但不是类型或类型的地址。为了便于理解,我们可以说 decltype 预计它的参数是一个变量,如下例所示。 int main() { int i = 10; decltype(i)j; decltype(int)k; / *编译器错误。 * / decltype(& int)l; / *编译器错误。 * / 返回0; } 您还希望编译器替换 D 与 :: free_int 。和 :: free_int 被传递在作为非类型模板参数。但是 D 是一个类型模板参数。非类型模板参数以实际类型开始(例如 int , struct a * 或类型模板名称) 。虽然类型模板参数以 typename 或 class 开头。非类型模板参数的一个简单示例 template< int INIT> void func2(void) { decltype(INIT)j = INIT; int main() { func2< 10>(); 返回0; 当你传入像之类的函数指针时:: free_int ,您需要非类型模板参数,它必须以类型开头。而你希望函数指针的类型是可替换的。所以函数指针的类型必须是类型模板参数。这些使他们成为两个模板参数。 这就是在模板< typename T,typename D,D F>中需要三个模板参数的原因。 code>,这是你最好的结果。 edit Possibly can't be done, see Clean implementation of function template taking function pointer although answer 1 there has a C macro work-around https://stackoverflow.com/a/18706623/2332068I'm passing a function into a template to become a pre-supplied argument to the constructor, but also need to use decltype on that function to pass the function type to unique_ptr<...> template instantiator(? is that the right word)It works if I pre-use decltype as an extra template argument, but not if I invoke it inside the template on the function passed as a parameter.I'm using g++ 4.9.2, and extending my explorations here Calling inherited template constructor of unique_ptr subclass where I subclass unique_ptr to have a fixed destructor, I find that some destructor functions do not return void, so I want a more generic template that does not need to specify the destructor function type.My current code is:void free_int(int* p) { delete p;}template<typename T, void (*D)(T*)>class unique_dptr : public std::unique_ptr<T, decltype(D)> { public: unique_dptr(T* t) : std::unique_ptr<T, decltype(D)>(t, D) { };};using int_ptr = unique_dptr<int, ::free_int>;int_ptr i(new int(2));but note the void (*D)(T*) calling signature to restrict the destructor to a void function that takes a pointer to TGiven normal use of unique_ptr in this form:unique_ptr<foo, decltype(&::free_foo)>I want to have something like this:template<typename T, typename D>class unique_gptr : public std::unique_ptr<T, decltype(&D)> { public: unique_gptr(T* t) : std::unique_ptr<T, decltype(&D)>(t, D) { };};using int_gptr = unique_gptr<int, ::free_int>;int_gptr ig(new int(2));but the compiler hates it:error: template argument 2 is invalidclass unique_gptr : public std::unique_ptr<T, decltype(&D)> { ^No doubt ancient C-macro style token pasting is what I am wrongly aiming at.I have tried removing the & from decltype(&D) but that leaves the error:error: argument to decltype must be an expressionhowever this is OK:template<typename T, typename D, D F>class unique_gptr : public std::unique_ptr<T, D> { public: unique_gptr(T* t) : std::unique_ptr<T, D>(t, F) { };};using int_gptr = unique_gptr<int, decltype(&::free_int), ::free_int>;int_gptr ig(new int(2));but I wonder what I am doing wrong that I can't manage move the decltype(&::free_int) into the template.Other solutionsI realise that I can just write additional specialisations for other fixed free-function types, replacing void(*)(void*)I realise that I can override the std::default_delete for my type.But this is really an exercise in template composition 解决方案 I think for c++11 it is impossible to achieve what you want.template<typename T, typename D>class unique_gptr : public std::unique_ptr<T, decltype(&D)> { public: unique_gptr(T* t) : std::unique_ptr<T, decltype(&D)>(t, D) { };};using int_gptr = unique_gptr<int, ::free_int>;int_gptr ig(new int(2));Notice that decltype is applied on D, which is declared as a typename. So D is a type. But decltype can't be used on a type.Firstly the code tries to get the address of a type (&). Secondly, the argument of decltype is expected to be an expression, but not a type or "the address of a type". To make it easier to understand, we can say that decltype expects its argument to be a "variable", like the following example.int main(){ int i = 10; decltype(i) j; decltype(int) k; /* Compiler error. */ decltype(&int) l; /* Compiler error. */ return 0;}You also want the compiler to replace D with ::free_int. And ::free_int is passed in as a non-type template argument. However D is a type template parameter. A non-type template parameter starts with an actual type (e.g. int, struct a* or a type template name). While a type template parameter starts with typename or class. An easier example for non-type template parameter,template<int INIT>void func2(void){ decltype(INIT) j = INIT;}int main(){ func2<10>(); return 0;}When you pass in a function pointer like ::free_int, you need a non-type template parameter, which must be preceded by a type. And you want the type of the function pointer to be "replaceable". So the type of the function pointer has to be a type template parameter. These make them two template parameters.That's the reason you need three template parameters in template<typename T, typename D, D F>, which is the best result you have. 这篇关于如何修复模板中的错误重构decltype的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-10 12:48