I'm trying to create some sort of comparison function that will compare certain prefixes that are known at compile time to other buffers.
I'm trying to use the predefined std::arrays that hold the prefixes as template parameters.
Here is what I tried:
constexpr std::array<std::uint8_t, 4> ARRAY_A {{0xDE, 0xAD, 0xBE, 0xEF}};
constexpr std::array<std::uint8_t, 4> ARRAY_B {{0xBA, 0xD, 0xF0, 0x0D}};
enum class Foo{
A,B
};
template<size_t SizeOfHeader, std::array<std::uint8_t, SizeOfHeader> Header, Foo f>
void foo()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<template<class, class> class TContainer, Foo f>
void foo2()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
foo2<ARRAY_A, Foo::A>();
foo<ARRAY_A.size(), ARRAY_A, Foo::A>();
return 0;
}
These attempts were made after reading the following answers which seemed related: 1 , 2.
I'm interested in understanding the errors in the code as much as finding a working solution :)
Here is the failed attempt at coliru. The errors are:
main.cpp:31:5: error: no matching function for call to 'foo2'
foo2<ARRAY_A, Foo::A>();
^~~~~~~~~~~~~~~~~~~~~
main.cpp:23:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'TContainer'
void foo2()
^
main.cpp:32:5: error: no matching function for call to 'foo'
foo<ARRAY_A.size(), ARRAY_A, Foo::A>();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:17:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Header'
void foo()
^
2 errors generated.
You cannot pass instances of class types as template non-type parameters.
You can pass references and pointers to class types, but not instances themselves.
There has been some discussion about permitting this in a future standard revision (after c++17).
Your code:
template<template<class, class> class TContainer, Foo f>
void foo2()
this takes a template template parameter, not an instance of that.
template<class, class>
class bob;
the template bob (not a class instance of it, or a value instance of a class instance of it) is a valid first template argument for foo2.
template<size_t SizeOfHeader, std::array<std::uint8_t, SizeOfHeader> Header, Foo f>
void foo()
this is not a valid template declaration. std::array<std::uint8_t, SizeOfHeader> is going to be ill-formed there. I doubt the compiler is mandated to diagnose this error immediately, because SizeOfHeader argument to array makes the type of array dependent.
You could pass directly the parameters using a variadic template, i.e.:
#include <type_traits>
template <typename... Ts>
typename std::enable_if<sizeof...(Ts) == 0>::type f()
{
}
template<std::uint8_t a, std::uint8_t... rest>
void f()
{
f<rest...>();
}
See variadic function template without formal parameters for details about the base case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With