Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建重复声明_C++_Templates - Fatal编程技术网

C++ 创建重复声明

C++ 创建重复声明,c++,templates,C++,Templates,我想知道是否有人知道一种创建重复类型声明的方法,因为这可能会让人困惑,举个例子会很有帮助: 对于我们的项目,我们需要有如下函数和类型声明: 使用FunType=std::function; 使用DataType=std::tuple; 分散在多个文件中,多次,最多32个翻倍(如果这很重要,仅翻倍) 我很乐意用以下假想代码行中的某些内容来代替手动写入/计算这些双倍: 使用FunType=something\u generate\u function\u decl; 使用DataType=some

我想知道是否有人知道一种创建重复类型声明的方法,因为这可能会让人困惑,举个例子会很有帮助:

对于我们的项目,我们需要有如下函数和类型声明:

使用FunType=std::function;
使用DataType=std::tuple;
分散在多个文件中,多次,最多32个翻倍(如果这很重要,仅翻倍)

我很乐意用以下假想代码行中的某些内容来代替手动写入/计算这些双倍:

使用FunType=something\u generate\u function\u decl;
使用DataType=something\u generate\u DataType\u decl
如果可能的话,我想远离boost及其预处理器库

编辑以提供一些说明

重要的是,在应用程序中的某个点上,我们得到一系列字节(表示一个双精度数组),每个值都有预定义的含义,我们需要对它们进行验证(每个值都需要使用几个有效性条件进行验证),拒绝无效的数据,记录相应的无效数据及其含义,在应用程序周围传递有意义的数据,从logger模块到十几个不同的地方,包括现有函数,以及具有已定义语法的Qt信号等。。。在某种程度上,这将从我们手中消失,所以这就是为什么我想要创建尽可能容易阅读和验证的代码

Edit2提供更多说明

阅读这些评论,似乎对这个问题的范围有很多困惑。问题中故意遗漏了大量信息,这些信息与问题的本质无关,即如何将这8个(或9个、或12个、或32个双倍)缩短为一个更易于管理的实体。丢失的信息是我们处理收到的数据的内部方式(我们有一个大规模的项目,因此您可以想象,数据有几个抽象层,在发送之前进行自动验证、转换等,因此不是整个应用程序都是一长串if/else语句和带参数的基本函数调用),对整个事件的唯一限制是,作为一个简单的双精度数组(表示一条消息)验证,然后发送到已经有预定义接口的functions/QT signals/C++11 lambdas。所有信息处理和验证都封装到类的层中,这些类只是在某个地方注册(不在本问题的范围内)用于接收、存储、验证和发送数据,例如,
FunType
(实际上是消息类的内部使用类型)表示函数/插槽/lambda的接口,其中包含特定消息(及其已验证的成员)将通过某种机制自动发送,该机制将所有成员聚集到一个元组(
DataType
)中,并使用一些
index\u序列
magic和可变模板,编译器将元组匹配到所需函数,该函数在某个时间点“订阅”此消息。
@管理员如果您觉得此编辑不相关,请随时删除它。

如果您可以使用Boost,它的预处理器库中有一个宏可以提供帮助。这应该可以:

#include <boost/preprocessor/repetition/enum.hpp>

#define TEXT(z, n, data) data

using FunType = std::function<void( BOOST_PP_ENUM(8, TEXT, double) )>;
using DataType = std::tuple< BOOST_PP_ENUM(8, TEXT, double) >;
#包括
#定义文本(z、n、数据)数据
使用FunType=std::function;
使用DataType=std::tuple
现场演示:

或者,使用附加的辅助宏更方便:

#define NDOUBLE(n) BOOST_PP_ENUM(n, TEXT, double)

using FunType = std::function<void( NDOUBLE(8) )>;
using DataType = std::tuple< NDOUBLE(8) >;
#定义双(n)BOOST_PP_ENUM(n,文本,双)
使用FunType=std::function;
使用DataType=std::tuple
现场演示:

这很容易:

太长了,读不下去了,这是个框架挑战,因为我想你问的问题不对。 对于我们的项目,我们需要有如下函数和类型声明:

现在,您的函数参数可以是强类型的:不接受任何8或32个双精度的序列,您可以保证在编译时传递的是正确类型的位置(如果有多个),以及位置,而不是速度或动量或其他任何东西


注意到还有很多改进的地方,但是首先是使用结构化数据类型而不是使用大的平面参数列表。

< P>不需要拖动进这个,这里是C++ 11解决方案:

#include <cstdint>

template<std::size_t N,typename R,typename T, typename...Args>
struct function_replicator{
    //Add an extra T that will be packed with Args... in the nested template.
    using type = typename function_replicator<N-1,R,T,T,Args...>::type;
};
template<typename R,typename T, typename...Args>
struct function_replicator<0,R,T,Args...>{
    //Args... holds N Ts
    using type = R(Args...);
};

template<std::size_t N,template<typename...CArgs>class Container,typename T, typename...Args>
struct container_replicator{
    using type = typename container_replicator<N-1,Container,T,T,Args...>::type;
};
template<template<typename...CArgs>class Container,typename T, typename...Args>
struct container_replicator<0,Container,T,Args...>{
    using type = Container<Args...>;
};

#include <tuple>
#include <functional>

// Feel free to make them more general.
template<std::size_t N>
using function_def = std::function<typename function_replicator<N,void,double>::type>;

template<std::size_t N>
using tuple_def = typename container_replicator<N,std::tuple,double>::type;


#include <type_traits>

int main(){
    //Keeping it C++11
    static_assert(std::is_same<function_def<3>,std::function<void(double,double,double)>>::value,"");
    static_assert(std::is_same<tuple_def<3>,std::tuple<double,double, double>>::value,"");
}
#包括
模板
结构函数复制器{
//在嵌套模板中添加一个额外的T,该T将与Args…打包。
使用type=typename函数\ u replicator::type;
};
模板
结构函数复制器{
//Args…持有N Ts
使用type=R(Args…);
};
模板
结构容器复制器{
使用type=typename容器\ u replicator::type;
};
模板
结构容器复制器{
使用类型=容器;
};
#包括
#包括
//请随意让它们更一般化。
模板
使用function_def=std::function;
模板
使用tuple_def=typename容器_replicator::type;
#包括
int main(){
//保持C++11
静态断言(std::is_same::value,“”);
静态断言(std::is_same::value,“”);
}

<>代码> 这里是纯C++的无升压或宏的解决方案,只是可变模板:

#include <tuple>
#include <utility>
#include <functional>

// tuple
template <typename T, std::size_t ... Is>
constexpr auto gft_helper (std::index_sequence<Is...> const &)
-> decltype(std::make_tuple( (Is, std::declval<T>())... ));

template <typename T, std::size_t N>
constexpr auto get_fixed_tuple ()
-> decltype(gft_helper<T>(std::make_index_sequence<N>{}));

template <typename T, std::size_t N>
using tuple_fixed_type = decltype(get_fixed_tuple<T, N>());

// function
template <typename T>
constexpr auto getType(int, T&& t)
-> typename std::decay<T>::type;

template <typename T, std::size_t ... Is>
constexpr auto gff_helper (std::index_sequence<Is...> const &)
-> std::function<void( decltype(getType(Is, std::declval<T>()))...)>;

template <typename T, std::size_t N>
constexpr auto get_fixed_function ()
-> decltype(gff_helper<T>(std::make_index_sequence<N>{}));

template <typename T, std::size_t N>
using function_fixed_type = decltype(get_fixed_function<T, N>());

int main()
{
    using FunType = function_fixed_type<double,4>;
    using DataType = tuple_fixed_type<double,4>;

    static_assert(std::is_same<DataType, std::tuple<double, double, double, double>>{} );
    static_assert(std::is_same<FunType, std::function<void(double, double, double, double)>>{} );
 }
#包括
#包括
#包括
//元组
模板
constexpr自动gft\u助手(std::index\u序列const&)
->decltype(std::make_tuple((Is,std::declval())…);
模板
constexpr自动获取固定的元组()
->decltype(gft_helper(std::make_index_sequence{}));
模板
使用tuple_fixed_type=decltype(get_fixed_tuple());
//作用
模板
constexpr自动获取类型(int、T和&T)
->typename std::decation::type;
模板
constexpr自动gff\u助手(std::index\u序列const&)
->std::函数;
模板
constexpr自动获取固定值函数()
->decltype(gff_helper(std::make_index_sequence{}));
模板
使用函数u-fix
template<class T> 
struct type_identity {
    using type = T;
};

template<template<class...> class Fn, class T, std::size_t n>
struct apply_repeat {
    template<std::size_t... is>
    static Fn<typename decltype(is, type_identity<T>{})::type...> 
        get_type(std::index_sequence<is...>);

    using type = decltype(get_type(std::make_index_sequence<n>{}));
};
 using FunType = std::function<void(double,double,double,double,double,double,double,double)>;
 using DataType = std::tuple<double,double,double,double,double,double,double,double>;
using FunType = something_generate_function_decl<8>;
void fun(double latitude, double longitude, double altitude)
{
  if(latitude > longitude &&
     longitude < 90 && longitude > 9 &&
     altitude > 0)
  {
    fly(longitude, latitude, altitude);
  }
}
struct LatLongPosition // just in case you have alternative representations
{
    double latitude;
    double longitude;
};

struct AirPosition
{
    LatLongPosition pos;
    double altitude;
};
#include <cstdint>

template<std::size_t N,typename R,typename T, typename...Args>
struct function_replicator{
    //Add an extra T that will be packed with Args... in the nested template.
    using type = typename function_replicator<N-1,R,T,T,Args...>::type;
};
template<typename R,typename T, typename...Args>
struct function_replicator<0,R,T,Args...>{
    //Args... holds N Ts
    using type = R(Args...);
};

template<std::size_t N,template<typename...CArgs>class Container,typename T, typename...Args>
struct container_replicator{
    using type = typename container_replicator<N-1,Container,T,T,Args...>::type;
};
template<template<typename...CArgs>class Container,typename T, typename...Args>
struct container_replicator<0,Container,T,Args...>{
    using type = Container<Args...>;
};

#include <tuple>
#include <functional>

// Feel free to make them more general.
template<std::size_t N>
using function_def = std::function<typename function_replicator<N,void,double>::type>;

template<std::size_t N>
using tuple_def = typename container_replicator<N,std::tuple,double>::type;


#include <type_traits>

int main(){
    //Keeping it C++11
    static_assert(std::is_same<function_def<3>,std::function<void(double,double,double)>>::value,"");
    static_assert(std::is_same<tuple_def<3>,std::tuple<double,double, double>>::value,"");
}
#include <tuple>
#include <utility>
#include <functional>

// tuple
template <typename T, std::size_t ... Is>
constexpr auto gft_helper (std::index_sequence<Is...> const &)
-> decltype(std::make_tuple( (Is, std::declval<T>())... ));

template <typename T, std::size_t N>
constexpr auto get_fixed_tuple ()
-> decltype(gft_helper<T>(std::make_index_sequence<N>{}));

template <typename T, std::size_t N>
using tuple_fixed_type = decltype(get_fixed_tuple<T, N>());

// function
template <typename T>
constexpr auto getType(int, T&& t)
-> typename std::decay<T>::type;

template <typename T, std::size_t ... Is>
constexpr auto gff_helper (std::index_sequence<Is...> const &)
-> std::function<void( decltype(getType(Is, std::declval<T>()))...)>;

template <typename T, std::size_t N>
constexpr auto get_fixed_function ()
-> decltype(gff_helper<T>(std::make_index_sequence<N>{}));

template <typename T, std::size_t N>
using function_fixed_type = decltype(get_fixed_function<T, N>());

int main()
{
    using FunType = function_fixed_type<double,4>;
    using DataType = tuple_fixed_type<double,4>;

    static_assert(std::is_same<DataType, std::tuple<double, double, double, double>>{} );
    static_assert(std::is_same<FunType, std::function<void(double, double, double, double)>>{} );
 }