使用 std::array<Type, N> 的实例作为模板参数
我正在尝试创建某种比较函数,将编译时已知的某些前缀与其他缓冲区进行比较。
我正在尝试使用将前缀作为模板参数保存的预定义
std::array
。
这是我尝试过的:
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;
}
这些尝试是在阅读以下看似相关的答案后做出的: 1 、 2 。
我对理解代码中的错误和找到可行的解决方案都很感兴趣:)
这里 是 coliru 的失败尝试。错误如下:
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.
不能将类类型的实例作为模板非类型参数传递。
您可以将引用和指针传递给类类型,但不能传递实例本身。
关于在未来的标准修订版中允许这样做( c++17 之后)已经有一些讨论。
您的代码:
template<template<class, class> class TContainer, Foo f>
void foo2()
这需要一个模板模板参数,而不是该模板参数的实例。
template<class, class>
class bob;
模板
bob
(不是它的类实例,也不是它的类实例的值实例)是
foo2
的有效第一个模板参数。
template<size_t SizeOfHeader, std::array<std::uint8_t, SizeOfHeader> Header, Foo f>
void foo()
这不是有效的模板声明。
std::array<std::uint8_t, SizeOfHeader>
在此处将出现格式错误。我怀疑编译器是否被要求立即诊断此错误,因为
array
的
SizeOfHeader
参数使
array
的类型相关。
您可以使用可变参数模板直接传递参数,即:
#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...>();
}
有关基本情况的详细信息,请参阅 没有形式参数的可变函数模板 。
另一种方法是使用
constexpr
函数,如果您想要强制执行编译时,您可以使用它(通过示例)初始化
constexpr
值。
不幸的是,您标记了 C++11,因此
constexpr
函数不太灵活。
以下是一个完整的 C++11 工作示例,其中包含一个
constexpr
函数,给定几个相同类型和维度的
std::array
,返回相应相等元素的数量。该值在
constexpr
val
变量中注册,此外,使用
static_assert
#include <array>
#include <cstdint>
template <typename T, std::size_t N>
constexpr std::size_t countEqual (std::array<T, N> const & a1,
std::array<T, N> const & a2,
std::size_t pos = 0U,
std::size_t count = 0U)
{
return pos < N ? countEqual(a1, a2, pos+1U,
a1[pos] == a2[pos] ? ++count : count)
: count;
}
int main (void)
{
constexpr std::array<std::uint8_t, 4> ARRAY_A {{0xDE, 0xAD, 0xBE, 0xEF}};
constexpr std::array<std::uint8_t, 4> ARRAY_B {{0xBA, 0xAD, 0xF0, 0x0D}};
constexpr auto val { countEqual(ARRAY_A, ARRAY_B) };
static_assert( val == 1U , "!" );
}