例如,我在头文件中有以下c ++代码
struct Data {
static const int N = 4;
static const int A[N];
};
以及cpp文件中的以下内容定义了数组A
内容。
const int Data::A[Data::N] = {1,2,2,1};
有没有办法编写模板来检测数组A
内容在编译时是否对称? (可能是c ++ 11功能支持,但我不熟悉它的功能......)
例如,如果DetectSymmetric<Data>::is_sym
的内容为true
和A
,则{1,2,2,1}
将为false
,例如,如果它等于{1,2,3,4}
答案 0 :(得分:4)
使用C ++ 11/14,您可以使用constexpr
函数:
const int A[4] = { 1,2,2,1 };
template<int N>
constexpr bool symmetric_helper( const int (&a)[N], int idx) {
return idx > 0 ? symmetric_helper<N>(a, idx - 1) && (a[idx - 1] == a[N - idx]) : true;
}
template<int N>
constexpr bool symmetric(const int (&a)[N]) {
return symmetric_helper<N>(a, N / 2);
}
std::cout << symmetric(A) << std::endl;
使用C ++ 14,您可以编写一个简单的for循环而不是递归,但C ++ 11对constexpr
函数有非常严格的限制。
答案 1 :(得分:2)
@Dutow是第一个有工作答案的人,但这也应该处理类型推导并能够使用任何类型的数组。
#include <cstddef>
template<typename T, size_t N, size_t O, size_t I>
struct detect_symmetric_array
{
static constexpr bool is_symmetric(T (&array)[N])
{
return array[O] == array[N - O - 1] && detect_symmetric_array<T, N, O + 1, I - 1>::is_symmetric(array);
}
};
template<typename T, size_t N, size_t O>
struct detect_symmetric_array<T, N, O, 1>
{
static constexpr bool is_symmetric(T(&array)[N])
{
return array[O] == array[N - O - 1];
}
};
template<typename T, size_t N>
constexpr bool is_symmetric_array(T (&array)[N])
{
return detect_symmetric_array<T, N, 0, N / 2>::is_symmetric(array);
}
int main(int argc, char** argv)
{
constexpr int first[4] = { 1, 2, 2, 1 }, second[4] = { 1, 2, 3, 4 }, third[5] = {1, 2, 3, 2, 1}, foruth[5] = {1,3,2,4,5};
static_assert(is_symmetric_array(first), "array first should be symmetric");
static_assert(is_symmetric_array(second) == false, "array second should not be symmetric");
static_assert(is_symmetric_array(third), "array third should be symmetric");
static_assert(is_symmetric_array(foruth) == false, "array fourth should not be symmetric");
}
答案 2 :(得分:0)
有很多模式可以做你要求的。
以下是我的方式。
我在variadic模板结构中修改了Data
结构;只是为了简化示例。
template <int ... Is>
struct Data
{
static constexpr int N { sizeof...(Is) };
static constexpr int A[N] { Is... };
};
template <typename T, int P1 = 0, int P2 = T::N-1, bool B = (P1 < P2)>
struct is_sym;
template <typename T, int P1, int P2>
struct is_sym<T, P1, P2, false>
{ constexpr static bool value = true; };
template <typename T, int P1, int P2>
struct is_sym<T, P1, P2, true>
{
constexpr static bool value
= (T::A[P1] == T::A[P2]) && is_sym<T, P1+1, P2-1>::value ;
};
int main ()
{
static_assert(is_sym<Data<1, 2, 3, 4>>::value == false, "!");
static_assert(is_sym<Data<1, 2, 2, 1>>::value == true, "!");
static_assert(is_sym<Data<1, 2, 3, 2, 1>>::value == true, "!");
return 0;
}
p.s:抱歉我的英语不好。
答案 3 :(得分:0)
这是一个C ++ 14解决方案(最小的工作示例):
#include<functional>
#include<cstddef>
struct Data {
static const int N = 4;
static constexpr int A[N] = {1,2,2,1};
static constexpr int B[N] = {1,1,3,1};
};
template<typename T, std::size_t... I>
constexpr bool f(const T *data, std::index_sequence<I...>) {
bool eq = true;
int arr[] = { (eq &= (data[I] == data[sizeof...(I)-I-1]), 0)... };
return eq;
}
template<typename T, std::size_t N>
constexpr bool f(const T(&data)[N]) {
return f(data, std::make_index_sequence<N>());
}
int main() {
static_assert(f(Data::A), "!");
static_assert(not f(Data::B), "!");
}
缺点是它遍历整个数组 它可以改进,但它留给读者练习。