您无需指定引用的确切类型。您可以使用占位符:
#include<array>
template <auto& ARRAY> class Foo {
static constexpr auto N = ARRAY.size();
};
constexpr std::array<int, 3> A{1, 2, 3};
void bar()
{
Foo<A> foo_a;
}
如果你想在模板参数不是对std::array<int, ...>的引用时得到一个错误,你可以写一个类型特征告诉你类型是否是std::array的实例化并检查value_type:
#include<array>
#include<type_traits>
template<typename>
struct is_std_array : std::false_type {};
template<typename T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};
template<typename T>
inline constexpr auto is_std_array_v = is_std_array<T>::value;
// std::remove_cvref_t will be part of C++20
template<typename T>
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
template<auto& ARRAY>
class Foo {
using ARRAY_type = remove_cvref_t<decltype(ARRAY)>;
static_assert(is_std_array_v<ARRAY_type>,
"Foo requires reference to std::array of int as template argument!");
static_assert(std::is_same_v<typename ARRAY_type::value_type, int>,
"Foo requires reference to std::array of int as template argument!");
constexpr static auto N = ARRAY.size();
};
constexpr std::array<int, 3> A{1, 2, 3};
constexpr std::array<long, 3> B{1, 2, 3};
constexpr int C = 5;
void bar()
{
Foo<A> foo_a;
// Foo<B> foo_b; // Will give static_assert error message
// Foo<C> foo_c; // Will give static_assert error message
}
在 C++20 中会有一些概念,这将允许您编写一个概念来测试我现在使用 static_asserts 测试的属性,您将能够使用该概念来代替 auto在模板参数中。