gpt4 book ai didi

c++ - 如何修复模板内的错误重构 decltype

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:43:45 25 4
gpt4 key购买 nike

编辑 可能无法完成,请参阅 Clean implementation of function template taking function pointer虽然答案 1 有一个 C 宏解决方法 https://stackoverflow.com/a/18706623/2332068


我将一个函数传递到模板中以成为构造函数的预提供参数,但还需要使用 decltype在该函数上将函数类型传递给 unique_ptr<...>模板实例化器(?这个词对吗)

如果我预先使用 decltype 就可以了作为一个额外的模板参数,但如果我在作为参数传递的函数的模板中调用它,则不会。

我正在使用 g++ 4.9.2,并在此处扩展我的探索 Calling inherited template constructor of unique_ptr subclass我在哪里子类 unique_ptr有一个固定的析构函数,我发现一些析构函数不返回 void , 所以我想要一个不需要指定析构函数类型的更通用的模板。

我当前的代码是:

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));

但请注意 void (*D)(T*)调用签名将析构函数限制为一个 void 函数,该函数接受指向 T 的指针

鉴于 unique_ptr 的正常使用以这种形式:

unique_ptr<foo, decltype(&::free_foo)>

我想要这样的东西:

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));

但编译器讨厌它:

error: template argument 2 is invalid
class unique_gptr : public std::unique_ptr<T, decltype(&D)> {
^

毫无疑问,古老的 C 宏样式标记粘贴是我错误的目标。

我试过删除 &来自 decltype(&D)但这留下了错误:

error: argument to decltype must be an expression

不过这没关系:

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));

但我想知道我做错了什么,我无法管理移动 decltype(&::free_int)进入模板。


其他解决方案

我意识到我可以为其他固定的自由函数类型编写额外的特化,替换 void(*)(void*)

我意识到我可以覆盖 std::default_delete适合我的类型。

但这确实是模板组合的练习

最佳答案

我认为对于 c++11 来说,不可能实现你想要的。

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));

注意 decltype适用于 D ,声明为 typename .所以D是一种类型。但是decltype不能用于类型

首先,代码尝试获取类型的地址 (&)。其次,decltype的说法应为表达式,但不是类型或“类型的地址”。为了更容易理解,我们可以说 decltype期望它的参数是一个“变量”,如下例所示。

int main()
{
int i = 10;
decltype(i) j;
decltype(int) k; /* Compiler error. */
decltype(&int) l; /* Compiler error. */
return 0;
}

您还希望编译器替换 D::free_int .和 ::free_int作为 non-type template 传入争论。然而D是类型模板参数。非类型模板参数以实际类型开头(例如 intstruct a* 或类型模板名称)。虽然类型模板参数以 typename 开头或 class .非类型模板参数的更简单示例,

template<int INIT>
void func2(void)
{
decltype(INIT) j = INIT;
}

int main()
{
func2<10>();
return 0;
}

当你传入一个像::free_int这样的函数指针时,您需要一个非类型模板参数,它前面必须有一个类型。并且您希望函数指针的类型是“可替换的”。所以函数指针的类型必须是类型模板参数。这些使它们成为两个模板参数。

这就是在 template<typename T, typename D, D F> 中需要三个模板参数的原因, 这是你得到的最好结果。

关于c++ - 如何修复模板内的错误重构 decltype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33435553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com