Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.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++_Variadic Templates_Template Meta Programming_Generic Programming_Typetraits - Fatal编程技术网

C++ 处理普通混合类型和非混合类型的可变模板

C++ 处理普通混合类型和非混合类型的可变模板,c++,variadic-templates,template-meta-programming,generic-programming,typetraits,C++,Variadic Templates,Template Meta Programming,Generic Programming,Typetraits,因此,我试图创建一个类型特征,它表示两个“外部”类类型是否相同 例如,std::vector与std::vector相同,我不关心类型特征的任何内部参数 我在尝试为此创建泛型类型特征时遇到的一个问题是,我只知道如何将类型化的变量模板与非类型化的模板分开处理,这似乎阻止了我将其泛型化 是否可以处理类型化和非类型化模板参数的任何排列 下面是我实现的(包括失败的例子): //g++-std=c++17 #包括 #包括 #包括 #包括 //如果外部类型不匹配 模板 结构是外部类型相同的:std::fal

因此,我试图创建一个类型特征,它表示两个“外部”类类型是否相同

例如,
std::vector
std::vector
相同,我不关心类型特征的任何内部参数

我在尝试为此创建泛型类型特征时遇到的一个问题是,我只知道如何将类型化的变量模板与非类型化的模板分开处理,这似乎阻止了我将其泛型化

是否可以处理类型化和非类型化模板参数的任何排列

下面是我实现的(包括失败的例子):

//g++-std=c++17
#包括
#包括
#包括
#包括
//如果外部类型不匹配
模板
结构是外部类型相同的:std::false\u类型{};
//如果比较类型的参数仅包含类型
//即std::vector
//(内部参数也是类型)
模板
结构是_outer _type _same
:std::true_type{};
//如果比较类型的参数仅包含非类型
//某个类名
模板
结构是_outer _type _same
:std::true_type{};
//如果比较类型的参数包含单个
//类型化参数后跟一些非类型化参数
//std::数组
模板
结构是_outer _type _same
:std::true_type{};
//对于参数具有模式的任何外部类型:
//单变量参数后跟一系列类型化参数:
模板
结构是_outer _type _same
:std::true_type{};
//这是为了使评估更加整洁:
模板
内联constexpr bool是\u外部\u类型\u相同\u v
=外部类型相同::值;
//无法处理的示例类型
//正确地使用上述结构模板:
模板
结构示例类型
{
A数据1;
B数据2;
常数int data3=C;
};
int main()
{   
//显示其故障位置的示例:

std::cout AFAIK没有通用的解决方案。我们要么需要反射,要么需要一些新类型的模板语法,允许参数是类型参数或非类型参数。@super我不确定我会称之为稀有。
std::array
是一个主要的使用案例,并且有很多类似于它的类用于矩阵和li的东西ke。@NathanOliver和
std::array
样式化的东西将与这里给出的双包解决方案一起使用。混合并不少见,以
非类型、类型、非类型的形式混合也很少见,其中as
类型..,非类型..
相当常见。@ElliottSmith是的,这就是我说你需要添加speci的意思具体化。
non-type
可以是一个包,但主要类型将需要一个专门化。
type,non-type…
type,type,non-type…
将是2个专门化。如果你添加10个,你应该有你想要的行为与一些可能丑陋的代码。可能重复
// g++ -std=c++17

#include <iostream>
#include <vector>
#include <array>
#include <type_traits>

// If the outer types don't match
template <typename, typename>
struct is_outer_type_same : std::false_type {};


// if the arguments of the compared Type contains only types
// ie. std::vector<int,std::allocator<int>>
// (the inner arguments are also types)

template <template<typename...> typename OuterType,
                   typename... InnerTypes1,
                   typename... InnerTypes2
         >
struct is_outer_type_same < OuterType<InnerTypes1...>,
                            OuterType<InnerTypes2...>
                          >
        : std::true_type {};


// if the arguments of the compared Type contains only non-types
// eg. SomeClassName<4,5,2>

template <template<auto...> typename OuterType,
                   auto... InnerVariables1,
                   auto... InnerVariables2
         >
struct is_outer_type_same < OuterType<InnerVariables1...>,
                            OuterType<InnerVariables2...>
                          >
        : std::true_type {};


// if the arguments of the compared Type contains a single
// typed-argument followed by some non-typed arguments
// ie. std::array<int, 4>

template <template<typename, auto...> typename OuterType,
        typename InnerType1, auto... InnerVariables1,
        typename InnerType2, auto... InnerVariables2
         >
struct is_outer_type_same < OuterType<InnerType1, InnerVariables1...>,
                            OuterType<InnerType2, InnerVariables2...>
                          >
        : std::true_type {};


// For any outer types whose arguments have the pattern:
// single variable argument followed by a sequence of typed arguments:

template <template<auto, typename...> typename OuterType,
    auto InnerVariable1, typename... InnerTypes1,
    auto InnerVariable2, typename... InnerTypes2
         >
struct is_outer_type_same < OuterType<InnerVariable1, InnerTypes1...>, 
                            OuterType<InnerVariable2, InnerTypes2...>
                          >
        : std::true_type {};


// This is to make it neater to evaluate:

template <typename S, typename T>
inline constexpr bool is_outer_type_same_v
                    = is_outer_type_same<S,T>::value;


// Example type that fails to be handled
// correctly by the above struct templates: 
template <typename A, typename B, int C>
struct ExampleType
{
    A data1;
    B data2;
    const int data3 = C;
};


int main ()
{   
    // Examples to show where it fails:

    std::cout << "Fails to find match for ExampleType: "

    << is_outer_type_same_v<ExampleType<double,int,2>,
                            ExampleType<double,int,2>>

    << std::endl << std::endl



    // Examples to show where it works:

    << "Finds correctly: " << std::endl


    << std::endl << "Matches for std::vector: "

    << is_outer_type_same_v<std::vector<int>,
                            std::vector<double>>

    << is_outer_type_same_v<std::vector<std::vector<int>>,
                            std::vector<double>>

    << is_outer_type_same_v<std::vector<std::array<int,3>>,
                            std::vector<double>>


    << std::endl << "Mismatches for std::vector: "

    << is_outer_type_same_v<int,
                            std::vector<int>>

    << is_outer_type_same_v<std::array<int, 3>,
                            std::vector<int>>

    << is_outer_type_same_v<std::array<std::vector<int>, 3>,
                            std::vector<int>>


    << std::endl << "Matches for std::array: "

    << is_outer_type_same_v<std::array<int, 3>,
                            std::array<double, 7>>

    << is_outer_type_same_v<std::array<std::vector<int>, 7>,
                            std::array<double, 2>>

    << is_outer_type_same_v<std::array<std::array<int,3>, 8>,
                            std::array<std::vector<double>, 5>>


    << std::endl << "Mismatches for std::array: "

    << is_outer_type_same_v<int,
                            std::array<int,2>>

    << is_outer_type_same_v<std::vector<int>,
                            std::array<int,8>>

    << is_outer_type_same_v<std::vector<std::array<int,3>>,
                            std::array<int,2>>

    << std::endl;

    return 0;
}