При компиляции этого кода с помощью -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);
, но я бы хотелесть что-то, что статически проверяется во время компиляции.
В этом решении упоминается использование специализации шаблона, но часть, в которой мы здесь работаем со структурой, это тот случай, когда я 'Я хотел бы использовать статические проверки шаблона.