gpt4 book ai didi

c++ - 必须存在不相关的专业才能编译?

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

下面的代码(编译和执行正确,做我想做的事)是我在编写一个类来存储各种类型的属性时遇到的一个奇怪的例子,这些属性需要能够在它不再知道它们时删除指针类型。我的解决方案是制作一个带有模板函数的 Deleter 类,该函数可以获取和存储其地址以删除特定类型。 我不明白为什么这段代码有效,特别是:

  • 为什么它没有命中断言?
  • 为什么/如何需要/使用(看似)无关的专业?

代码:

#include <iostream>
#include <string>
#include <cassert>

#include <locale> //Just here as an unused class to specialize

using namespace std;

typedef void(*void_voidptr_func_t)(void*);

class ClassWithDestructor {
public:
~ClassWithDestructor() {
cout << "Destroyed\n";
}
};

class Deleter {
public:
template <class T>
static void Delete (T* ptr) {
assert(0);
}

//locale here can be any class
//it doesn't matter what class it is
//but if this specialization doesn't exist
//compile fails
template <class locale>
static void Delete(void* ptr) {
delete (locale*)ptr;
}
};

void* void_ptr_to_T = NULL;
void_voidptr_func_t T_delete_function = NULL;

template<class T>
void A() {
T* t = new T;
void_ptr_to_T = (void*)t;
T_delete_function = &Deleter::Delete<T>;
}

int main(int argc, char** argv) {
A<ClassWithDestructor>();
T_delete_function(void_ptr_to_T);
}

编译器:MSVC++ 2010,Microsoft Extensions Disabled

输出:

Destroyed

最佳答案

这个

template <class locale>
static void Delete(void* ptr) {
delete (locale*)ptr;
}

不是专业。这是一个过载。特化是这样的

template <>
static void Delete(locale* ptr) {
delete (locale*)ptr;
}

所以实际上相当于只写了

template <class T>
static void Delete(void* ptr) {
delete (T*)ptr;
}

其实你呈现的行为是因为线路上的重载决议

T_delete_function = &Deleter::Delete<T>;

第二个重载更具体,因为它接受 void*而不是 T*并且类型是明确指定的。因此,在存在上述过载 的情况下,它会选择它并编译并正常运行。在没有这个更具体的重载的情况下,编译器会调用另一个合适但更通用的重载来触发断言。

您可以仔细检查,即删除 #include <locale>行:编译器不会提示 class locale未声明。

关于c++ - 必须存在不相关的专业才能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6885125/

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