我试图创建某种比较函数,将比较编译时已知的某些前缀到其他缓冲区。
我尝试使用包含前缀作为模板参数的预定义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;
}
我有兴趣了解代码中的错误,就像找到有效的解决方案一样:)
Here是对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.
答案 0 :(得分:4)
您不能将类类型的实例作为模板非类型参数传递。
您可以将引用和指针传递给类类型,但不能传递实例本身。
在未来的标准修订版中(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>
在那里会变得不健全。我怀疑编译器是否被要求立即诊断此错误,因为SizeOfHeader
的{{1}}参数使array
的类型依赖。
答案 1 :(得分:2)
您可以使用可变参数模板直接传递参数,即:
#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...>();
}
有关基本情况的详细信息,请参阅variadic function template without formal parameters。
答案 2 :(得分:1)
另一种方法是使用constexpr
函数,如果要强制执行编译时,可以使用它来(例如)初始化constexpr
值。
不幸的是,您标记了C ++ 11,因此constexpr
函数的灵活性较低。
以下是一个带有constexpr
函数的完整C ++ 11工作示例,给定了几个相同类型和维度的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 , "!" );
}