【发布时间】:2019-03-17 22:26:39
【问题描述】:
使用-Waddress编译此代码时:
#include <iostream>
#include <memory>
#include <string.h>
template <typename T, void (*func)(T*) = nullptr>
struct Caller {
Caller(T* ptr = nullptr)
{
std::cout
<< "Creating caller " << ptr
<< ", is function " << std::is_function<decltype(func)>()
<< ", is null " << std::is_null_pointer<decltype(func)>()
<< ", function is " << func
<< std::endl;
if (func)
{
std::cout << "Running for " << ptr << " func " << func << std::endl;
func(ptr);
}
}
};
void free_char(char *c) { free(c); }
int main() {
Caller<char, free_char>(strdup("Test"));
Caller<const char>("Test2");
return 0;
}
它会失败:
/tmp/foo.cpp: In instantiation of ‘Caller<T, func>::Caller(T*) [with T = char; void (* func)(T*) = free_char]’:
/tmp/foo.cpp:36:40: required from here
/tmp/foo.cpp:13:33: warning: the address of ‘void free_char(char*)’ will never be NULL [-Waddress]
一种解决方法是使用 if (auto f = func) f(ptr); 之类的东西,但我希望在编译时进行静态检查。
This solution 提到了模板专业化的使用,但这里我们正在处理结构的一部分,这是我想使用静态模板检查的情况。
【问题讨论】:
-
对不起,你为什么不能使用模板专业化?
-
为什么不在构造函数中取一个函数指针呢? coliru.stacked-crooked.com/a/60f81dec07918597
-
if constexpr在 C++17 中。 -
@Jarod42 是的,我知道这一点,但如前所述,我们还没有准备好 :)
-
@NathanOliver 因为它需要是一个类型,我只是通过传递一个新模板来生成新的。