'Explicit template instantiation for a templated function parameter

I want to write the definition of a templated function in the .cpp file, instead of it being in the header.

Let's take this simple example:

// func.h

template <class T>
void print_message(T func) {
    func();
}

// main.cpp

#include <iostream>
#include "func.h"

void say_hello() {
    std::cout << "hello" << std::endl;
}

int main(int argc, char* argv[]) {
    print_message(say_hello);
    return 0;
}

How do I template instantiate the print_message function explicitly in the .cpp file, along the lines of how it is described here.

I tried the following code snippet but I get this error: explicit instantiation of 'print_message' does not refer to a function template, variable template, member function, member class, or static data member.

// func.h
template <class T>
void print_message(T func) {
    func();
}

// main.cpp

#include <iostream>
#include "func.h"

void say_hello() {
    std::cout << "hello" << std::endl;
}

template void print_message<say_hello>(say_hello func);

int main(int argc, char* argv[]) {
    print_message(say_hello);
    return 0;
}


Solution 1:[1]

The issue is not that you provide the definition in the source. You did place the definition in the header. Moreover there is only a single translation unit in your example. The error would be the same if you place all code in main.cpp.

The issue is that print_message has a type argument, but say_hello is not a type.

This compiles whithout error:

#include <iostream>

// func.h
template <class T>
void print_message(T func) {
    func();
}

// main.cpp
void say_hello() {
    std::cout << "hello" << std::endl;
}

template void print_message<decltype(&say_hello)>(decltype(&say_hello) func);

int main(int argc, char* argv[]) {
    print_message(&say_hello);
    return 0;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 463035818_is_not_a_number