c++;编译时检测对称数组的模板编程 例如,我在头文件中有以下C++代码 struct Data { static const int N = 4; static const int A[N]; };

c++;编译时检测对称数组的模板编程 例如,我在头文件中有以下C++代码 struct Data { static const int N = 4; static const int A[N]; };,c++,arrays,templates,c++11,C++,Arrays,Templates,C++11,并在其cpp文件中添加以下内容,以定义数组A内容 const int Data::A[Data::N] = {1,2,2,1}; 有没有办法编写一个模板来检测数组a内容在编译时是对称的?(可能c++11特性支持这一点,但我不熟悉它的特性…) 例如,如果A的内容是{1,2,2,1}和false,那么检测对称::is_sym将是true,如果它等于{1,2,3,4}与C++11/14一起,您可以使用constexpr函数: const int A[4] = { 1,2,2,1 }; templ

并在其cpp文件中添加以下内容,以定义数组
A
内容

const int Data::A[Data::N] = {1,2,2,1};
有没有办法编写一个模板来检测数组
a
内容在编译时是对称的?(可能c++11特性支持这一点,但我不熟悉它的特性…)


例如,如果
A
的内容是
{1,2,2,1}
false
,那么
检测对称::is_sym
将是
true
,如果它等于
{1,2,3,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;
const int A[4]={1,2,2,1};
模板
constexpr bool对称辅助对象(const int(&a)[N],int idx){
返回idx>0?对称的(a,idx-1)和&(a[idx-1]==a[N-idx]):true;
}
模板
constexpr bool对称(const int(&a)[N]){
返回对称的辅助对象(a,N/2);
}

std::cout@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");
}
#包括
模板
结构检测对称数组
{
静态constexpr bool是对称的(T(&数组)[N])
{
返回数组[O]==array[N-O-1]&&detect\u symmetric\u array::is\u symmetric(array);
}
};
模板
结构检测对称数组
{
静态constexpr bool是对称的(T(&数组)[N])
{
返回数组[O]==数组[N-O-1];
}
};
模板
constexpr bool是对称数组(T(&数组)[N])
{
返回检测对称数组::是否对称(数组);
}
int main(int argc,字符**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};
静态断言(是对称数组(第一),“数组第一应该是对称的”);
静态_断言(is_symmetric_array(second)=false,“array second不应对称”);
静态断言(是对称数组(第三个),“第三个数组应该是对称的”);
静态断言(是对称数组(foruth)=false,“第四个数组不应该是对称的”);
}

有很多模式可以满足您的要求

以下是我的方式

我已经修改了变量模板结构中的
数据
结构;只是为了简化这个例子

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;
 }
模板
结构数据
{
静态constexpr int N{sizeof…(Is)};
静态constexpr int A[N]{Is…};
};
模板
结构是_sym;
模板
结构是_sym
{constexpr static bool value=true;};
模板
结构是_sym
{
constexpr静态布尔值
=(T::A[P1]==T::A[P2])&&is_sym::value;
};
int main()
{
静态断言(is_sym::value==false,“!”;
静态断言(is_sym::value==true,“!”;
静态断言(is_sym::value==true,“!”;
返回0;
}
p、 s:很抱歉我的英语不好。

这里有一个C++14解决方案(最低限度,工作示例):

#包括
#包括
结构数据{
静态常数int N=4;
静态constexpr int A[N]={1,2,2,1};
静态constexpr int B[N]={1,1,3,1};
};
模板
constexpr bool f(const T*数据,std::index_序列){
布尔均衡=真;
int arr[]={(eq&=(数据[I]==数据[sizeof…(I)-I-1]),0)…};
返回均衡器;
}
模板
常数表达式布尔f(常数T和数据)[N]){
返回f(数据,std::make_index_sequence());
}
int main(){
静态断言(f(数据::A),“!”;
静态断言(不是f(数据::B),“!”;
}
缺点是它会迭代整个数组。

它可以改进,但留给读者作为练习。

sizeof(a)
=
sizeof(const int*)
。此外,我猜你的意思是在助手中的非对称助手
非对称助手。
const int(&a)[N]
再次使
sizeof(a)
be
N*sizeof(int)
,避免不必要的拷贝。
#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), "!");
}