I'm currently working on a C++20 project where I need to implement a series of overloaded functions using template matching. I am trying to create a set of function templates that can distinguish between different categories of types (e.g., integral types, floating-point types, and custom classes) and handle each with a specialized algorithm.
However, I'm running into an issue where the compiler is not selecting the most specialized template overload as I expected. I've simplified my code to illustrate the problem:
#include <iostream>
#include <type_traits>
// Overload for integral types
template<typename T>
requires std::is_integral_v<T>
void process(T value) {
std::cout << "Integral: " << value << std::endl;
}
// Overload for floating-point types
template<typename T>
requires std::is_floating_point_v<T>
void process(T value) {
std::cout << "Floating-point: " << value << std::endl;
}
// Overload for custom class
class MyCustomClass {};
template<>
void process<MyCustomClass>(MyCustomClass value) {
std::cout << "MyCustomClass instance" << std::endl;
}
int main() {
process(10); // Should call the integral overload
process(3.14); // Should call the floating-point overload
process(MyCustomClass()); // Should call the custom class overload
}
When I compile this code with g++ (GCC) 10.2.0
, I receive an error that suggests the compiler is unable to deduce the correct overload:
error: template-id ‘process’ for ‘void process(MyCustomClass)’ does not match any template declaration’
I'm looking for guidance on the following points:
MyCustomClass
?I've checked CPPReference and other Stack Overflow questions but haven't found a solution that resolves my issue. I'm compiling with the -std=c++20
flag.
The problem is that you don't have a primary template in your code to explicitly specialize!
This means that to resolve the error, you can either provide a primary template or change the explicit specialization to a non-template overload.
Here we provide a primary template as shown below:
//added this primary template
template<typename T>
void process(T);
//other code as before
Second way is to just provide an ordinary non-template overload instead of an explicit specialization:
//note the template<> has been removed from here
void process(MyCustomClass value) {
std::cout << "MyCustomClass instance" << std::endl;
}