Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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_C++11_Lambda_Template Meta Programming - Fatal编程技术网

C++ 基于部分模板的专门化与显式部分模板专门化

C++ 基于部分模板的专门化与显式部分模板专门化,c++,templates,c++11,lambda,template-meta-programming,C++,Templates,C++11,Lambda,Template Meta Programming,给定一个模板,例如foo: template<typename... ARGS> struct foo {}; 第二个部分专门化不是比第一个更专门化,并且必须实例化而不是模板参数专门化吗? 一些背景: 我目前正在为基于的模板元编程编写多变量lambda表达式 如本文所示,如果给定类似Haskell的let表达式,可以很容易地开发tmp lambda表达式。在我的例子中,我扩展了论文的内容,开发了基于变量模板的多变量let表达式(通过转换多个嵌套的一元let表达式),然后实现了多变量

给定一个模板,例如
foo

template<typename... ARGS>
struct foo {};
第二个部分专门化不是比第一个更专门化,并且必须实例化而不是模板参数专门化吗?

一些背景: 我目前正在为基于的模板元编程编写多变量lambda表达式

如本文所示,如果给定类似Haskell的
let
表达式,可以很容易地开发tmp lambda表达式。在我的例子中,我扩展了论文的内容,开发了基于变量模板的多变量let表达式(通过转换多个嵌套的一元let表达式),然后实现了多变量lambda表达式

我的lambda表达式模板,
tml::multi_lambda
,定义如下:

template<typename BODY , typename... VARIABLES>
struct multi_lambda
{
    template<typename... ARGS>
    using result = tml::eval<tml::multi_let<VARIABLES...,
                                            ARGS...,
                                            BODY
                                           >>;
};
template<typename VARIABLE , typename VALUE , typename BODY>
struct lambda
{
    template<typename ARG>
    using result = tml::eval<tml::let<VARIABLE , ARG , BODY>>;
};
tml::eval
实例化通用模板专门化(为通用可计算表达式设计),而不是lambda的部分专门化

编辑:tml::eval和SSCCE的实施
tml::eval
是一个元函数,用于计算任何类型的表达式,并返回结果。默认实现专门用于三种情况:

  • 表达式不是函数,只是一个值:计算此类表达式的结果是表达式本身:

    template<typename E>
    struct evaluate_impl<E>
    {
        using result = E;
    }; 
    
  • 表达式是一个函数,将更多参数传递到
    tml::eval
    以使用该自定义参数对表达式求值:忽略表达式的参数并传递和求值自定义参数:

    template<template<typename...> class F , typename... PLACEHOLDERS , typename... ARGS>
    struct evaluate_impl<F<PLACEHOLDERS...>,ARGS...> : public F<tml::eval<ARGS>...>
    {};
    
    最后,用户可以专门化
    eval_impl
    来覆盖默认行为,或使角落案例工作。例如,我的单变量lambda表达式模板,定义如下:

    template<typename BODY , typename... VARIABLES>
    struct multi_lambda
    {
        template<typename... ARGS>
        using result = tml::eval<tml::multi_let<VARIABLES...,
                                                ARGS...,
                                                BODY
                                               >>;
    };
    
    template<typename VARIABLE , typename VALUE , typename BODY>
    struct lambda
    {
        template<typename ARG>
        using result = tml::eval<tml::let<VARIABLE , ARG , BODY>>;
    };
    
    我遇到问题的多变量lambda表达式采用类似的方法:

    template<typename... VARIABLES , typename BODY , typename... ARG>
    struct evaluate_impl<tml::multi_lambda<BODY,VARIABLES...>,ARGS...>
    {
        using result = typename tml::multi_lambda<BODY,VARIABLES...>::template result<ARGS...>;
    };
    
    在以下情况下,
    lambda_2
    的评估失败:

    
    functional.hpp:167:76:错误:“struct tml::impl::evaluate_impl”的类模板实例化不明确
    使用eval=typename impl::evaluate\u impl::result;
    ^
    functional.hpp:116:16:错误:候选项为:struct tml::impl::evaluate\u impl
    结构评估\u impl:
    ^
    在main.cpp:24:0中包含的文件中:
    lambda.hpp:160:16:错误:struct tml::impl::evaluate\u impl
    结构评估\u impl:
    


    我使用的是GCC4.8.2

    它看起来像是在您的multi_lambda中,您正在用变量声明模板。。。最后

    template<typename BODY , typename... VARIABLES>
    struct multi_lambda
    {
        //...
    };
    
    模板
    结构多λ
    {
    //...
    };
    
    也许在您的使用中,您应该使用:

    using lambda_2 = tml::multi_lambda<F<_1,_1,_2,_2>,_1,_2>;
    
    使用lambda_2=tml::multi_lambda;
    
    首先,您应该真正了解什么是SSCCE,尤其是的“完整”部分。另外,。也就是说,我试图创建一个SSCCE,它似乎重现了您的问题,请参见我的答案末尾。查看您收到的错误消息,第三个专门化的实际代码看起来更像

    template<template<typename...> class F ,
             typename... PLACEHOLDERS ,
             typename ARG ,
             typename... ARGS>
    struct evaluate_impl<F<PLACEHOLDERS...>,ARG,ARGS...>
        : public F<tml::eval<ARG,ARGS>...>
    {};
    
    这个问题可能会消失

    最后,我曾经得到过一个和你相似的错误


    更新:使用下面评论中的SSCCE,只需在
    foo
    时禁用
    F
    的专门化,即可解决这种情况。情况如下所示:

    typename std::enable_if<!std::is_same<F<>,foo<>>::value>::type
    
    typename std::enable_if,foo>::value>::type
    

    或者根据您的SSCCE查看完整的。这样,您也可以添加
    ARG
    ,因为这两个专门化现在应该是相互排斥的。

    @DieterLücking写一个显式名称而不是那个示例?您的意思是“第一个部分专门化不是比第二个更显式…”谢谢您的建议。我指的是第二个(fooone),而不是第一个(通用模板参数
    T
    one)。你能提供一个SSCCE来显示你的问题吗?@Danvil你为什么这么认为?哦,对不起,那是个打字错误:(感谢您的努力。您是对的,第三个专门化确实使用了一个额外的arg来拒绝无参数的情况。为了简化问题,我省略了这一点。这是大量的代码,当我发布问题时,我试图描述实际的问题,而不只是复制粘贴整个库。但是您是对的ht,我在这个问题上发表了一篇好的SSCCE文章,这是非常错误的。我有很多问题要写一个简单的工作示例,而不发表数百行模板元编程代码:(另外,您的SSCCE正是我所处的情况。非常感谢。@Manu343726您是否可以按照我的建议,删除
    ARG
    以解决您的问题?您仍然可以使用
    static\u assert(sizeof…(ARGS)>0“至少需要一个ARGS”拒绝无参数情况)
    如果您需要,请在结构中。否则,请将我的SSCE扩展到显示您需要的内容,这样每个人都有公平的机会来帮助您。嗯,我可以根据参数包的长度尝试进行SFINAE。谢谢,我明天会尝试。我将发表评论(可能还会对问题进行编辑)关于结论。谢谢。@Manu343726欢迎来到§14.8.2.4的精彩世界。看看9/10,并确保你阅读了它,这实际上是由此产生的。鉴于你的问题,我们讨论了你的实际案例可能是什么的几个选项,每个选项都需要不同的具体分析。如果你对此感兴趣,我建议你接受了一个案例,并向相应的SSCCE提出了一个新问题。
    template<typename BODY , typename... VARIABLES>
    struct multi_lambda
    {
        //...
    };
    
    using lambda_2 = tml::multi_lambda<F<_1,_1,_2,_2>,_1,_2>;
    
    template<template<typename...> class F ,
             typename... PLACEHOLDERS ,
             typename ARG ,
             typename... ARGS>
    struct evaluate_impl<F<PLACEHOLDERS...>,ARG,ARGS...>
        : public F<tml::eval<ARG,ARGS>...>
    {};
    
    template<template<typename...> class F ,
             typename... PLACEHOLDERS ,
             typename... ARGS>
    struct evaluate_impl<F<PLACEHOLDERS...>,ARGS...>
        : public F<tml::eval<ARGS>...>
    {};
    
    typename std::enable_if<!std::is_same<F<>,foo<>>::value>::type