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
Templates 重载模板函数演绎错误_Templates_C++17_Variadic Templates_Sfinae_Generic Lambda - Fatal编程技术网

Templates 重载模板函数演绎错误

Templates 重载模板函数演绎错误,templates,c++17,variadic-templates,sfinae,generic-lambda,Templates,C++17,Variadic Templates,Sfinae,Generic Lambda,我努力做到这一点。我想创建重载模板函数,使此类调用成为可能并正确(GMock): ASSERT_EQ(最小(1,2,1); ASSERT_EQ(min(std::less(),3,2),2); 自动防抱死制动系统组件=[](自动el1,自动el2){ 返回标准::abs(el1)

我努力做到这一点。我想创建重载模板函数,使此类调用成为可能并正确(GMock):

ASSERT_EQ(最小(1,2,1);
ASSERT_EQ(min(std::less(),3,2),2);
自动防抱死制动系统组件=[](自动el1,自动el2){
返回标准::abs(el1)<标准::abs(el2);
};
断言等式(最小值(绝对值-1,-5),-1);
断言等式(最小值(4,3,2,1,1);
除此之外,一切都很好:

ASSERT_EQ(min(std::less<>(), 3,2,1), 2);
ASSERT_EQ(min(std::less(),3,2,1),2);
当我提取函数本身以得到一个有意义的错误时:

min(std::less<>(), 3,2,1)
min(标准::less(),3,2,1)
我明白了:

In file included from /home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/container_minimum_test.cpp:4:
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h: In instantiation of ‘First cppchallenge::lang::min(First, Args ...) [with First = int; Args = {}; <template-parameter-1-3> = std::enable_if<true, void>]’:
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:17:30:   required from ‘First cppchallenge::lang::min(First, Args ...) [with First = std::less<void>; Args = {int}; <template-parameter-1-3> = std::enable_if<false, void>]’
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:17:19:   required from ‘First cppchallenge::lang::min(First, Args ...) [with First = std::less<void>; Args = {int, int, int}; <template-parameter-1-3> = std::enable_if<false, void>]’
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/container_minimum_test.cpp:40:33:   required from here
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:17:30: error: no matching function for call to ‘min()’
         return min(first, min(args...));
                           ~~~^~~~~~~~~
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:8:7: note: candidate: ‘template<class T> T cppchallenge::lang::min(T, T)’
     T min(T first, T second) {
       ^~~
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:8:7: note:   template argument deduction/substitution failed:
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:17:30: note:   candidate expects 2 arguments, 0 provided
         return min(first, min(args...));
                           ~~~^~~~~~~~~
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:16:11: note: candidate: ‘template<class First, class ... Args, class> First cppchallenge::lang::min(First, Args ...)’
     First min(First first, Args... args) {
           ^~~
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:16:11: note:   template argument deduction/substitution failed:
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:17:30: note:   candidate expects at least 1 argument, 0 provided
         return min(first, min(args...));
                           ~~~^~~~~~~~~
gmake[3]: *** [CMakeFiles/ModernCppChallengeLang.dir/build.make:102: CMakeFiles/ModernCppChallengeLang.dir/tst/lang/container_minimum_test.cpp.o] Error 1
gmake[2]: *** [CMakeFiles/Makefile2:116: CMakeFiles/ModernCppChallengeLang.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:128: CMakeFiles/ModernCppChallengeLang.dir/rule] Error 2
gmake: *** [Makefile:177: ModernCppChallengeLang] Error 2
包含在/home/rumcajs/CLionProjects/moderncppkchallenge/tst/lang/container\u minimum\u test.cpp:4中的文件中:
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/./../src/lang/container_minimum.h:在“第一个cppchallenge::lang::min(第一个,Args…[with First=int;Args={};=std::enable_if]”的实例化中:
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/./../src/lang/container_minimum.h:17:30:从“第一个cppchallenge::lang::min(第一个,Args…[with First=std::less;Args={int};=std::enable_if]开始需要”
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/./../src/lang/container_minimum.h:17:19:从'First cppchallenge::lang::min(First,Args…[with First=std::less;Args={int,int,int};=std::enable_if]开始需要'
/home/rumcajs/CLionProjects/moderncppkchallenge/tst/lang/container\u minimum\u test.cpp:40:33:从这里开始需要
/home/rumcajs/CLionProjects/moderncpchallenge/tst/lang/../../src/lang/container_minimum.h:17:30:错误:调用“min()时没有匹配的函数”
返回最小值(第一个,最小值(参数…);
~~~^~~~~~~~~
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:8:7:注意:候选者:'template-cppchallenge::lang::min(T,T)'
T最小值(T第一,T第二){
^~~
/home/rumcajs/CLionProjects/moderncpchallenge/tst/lang/../../src/lang/container_minimum.h:8:7:注意:模板参数推断/替换失败:
/home/rumcajs/CLionProjects/moderncpchallenge/tst/lang/../../src/lang/container_minimum.h:17:30:注意:候选人需要2个参数,提供0个参数
返回最小值(第一个,最小值(参数…);
~~~^~~~~~~~~
/home/rumcajs/CLionProjects/ModernCppChallenge/tst/lang/../../src/lang/container_minimum.h:16:11:注意:候选:“模板第一个CPPCChallenge::lang::min(第一个参数…)
第一分钟(第一分钟,Args…Args){
^~~
/home/rumcajs/CLionProjects/moderncpchallenge/tst/lang/../../src/lang/container_minimum.h:16:11:注意:模板参数推断/替换失败:
/home/rumcajs/CLionProjects/moderncpchallenge/tst/lang/../../src/lang/container_minimum.h:17:30:注意:候选者至少需要1个参数,提供0个
返回最小值(第一个,最小值(参数…);
~~~^~~~~~~~~
gmake[3]:***[CMakeFiles/moderncpchallengelang.dir/build.make:102:CMakeFiles/moderncpchallengelang.dir/tst/lang/container\u minimum\u test.cpp.o]错误1
gmake[2]:***[CMakeFiles/Makefile2:116:CMakeFiles/moderncpchallengelang.dir/all]错误2
gmake[1]:***[CMakeFiles/Makefile2:128:CMakeFiles/moderncpchallengelang.dir/rule]错误2
gmake:**[Makefile:177:ModernCppChallengeLang]错误2
模板功能如下:

namespace cppchallenge::lang {
    //#1
    template<typename T>
    T min(T first, T second) {
        return first < second ? first : second;
    }

    template<typename First, typename... Args>
    using are_same = std::conjunction<std::is_same<First, Args>...>;

    //#2
    template<typename First, typename... Args, typename = std::enable_if<are_same<First, Args...>::value, void>>
    First min(First first, Args... args) {
        return min(first, min(args...));
    }

    //#3
    template<typename Comparator, typename T>
    T min(Comparator comp, T first, T second) {
        return comp(first, second) ? first : second;
    }

    //#4
    template<typename Comparator, typename First, typename... Args,
    typename = std::enable_if<are_same<First, Args...>::value, void>,
    typename std::enable_if<std::is_convertible<Comparator, std::function<bool(First,First)>>::value>::type>
    First min(Comparator comp, First first, Args... args) {
        return min(comp, first, min(comp, args...));
    }
}
namespace cppcchallenge::lang{
//#1
模板
T最小值(T第一,T第二){
返回第一个<第二个?第一个:第二个;
}
模板
使用are_same=std::连词;
//#2
模板
第一分钟(第一分钟,Args…Args){
返回最小值(第一个,最小值(参数…);
}
//#3
模板
T最小值(比较器补偿,T第一,T第二){
返回薪酬(第一,第二)?第一:第二;
}
//#4
模板
第一分钟(比较器补偿、第一优先、参数…参数){
返回最小值(comp,first,min(comp,args…);
}
}

错误指向函数#2,尽管它应该使用#4。

我想错误在以下模板函数中:您必须在最后一个
之后添加
*=nullptr
:type

template<typename Comparator, typename First, typename... Args,
typename = std::enable_if<are_same<First, Args...>::value, void>,
typename std::enable_if<std::is_convertible<Comparator, std::function<bool(First,First)>>::value>::type * = nullptr> // add * = nullptr
First min(Comparator comp, First first, Args... args) {
    return comp(comp, first, min(comp, args...));
}
最后一个
void
本身没有意义(前面的
std::enable\u如果
没有多大用处;但这是另一个问题;请参阅下面的“奖金建议”)

您应该在类似于

template <typename Comparator, typename First, typename ... Args,
          typename = std::enable_if<are_same<First, Args...>::value, void>
          void * = nullptr>
//............^^^^^^^^^^^^
否则,测试将无法工作,并且该功能将一直处于启用状态(从
First
Args…
类型的角度来看)

SFINAE测试中的类似问题

First min(First first, Args... args) 

你确定第四种方法可用吗?你传递一个模板lambda并尝试将其转换为一个非模板。不幸的是,我不确定,情况就是这样。我想指定第一个参数是一个比较器,而不是要比较的值列表的第一个元素。我认为这是一种解决方案,但我愿意接受建议ns.您是否尝试过使用命名模板函数?您有什么想法?更改函数的名称?我特别希望避免放弃重载。template bool abs_comp(tel1,tel2){return std::abs(el1)std::is_convertable::value
,它可以工作。为什么添加
*=nullptr
?@AmirRasulov-是的,
std::is_convertable::value
本身可以工作;但是您必须在函数的模板签名上下文中看到它;我已经改进了答案;我希望现在如果更清楚。@LeśnyRumcajs-还可以检查其他SFINAE测试:有时当您应该使用
std::enable_if
时,您可以使用
std::enable_if_if_t
@max66,谢谢您的解释!如果我理解问题是在
typename std::enable_if::type>
中忘记的
=
?@AmirRasulov-忘记的
typename=/code>befofo的再利用
template <typename Comparator, typename First, typename ... Args,
          typename = std::enable_if<are_same<First, Args...>::value, void>
          void * = nullptr>
//............^^^^^^^^^^^^
template <typename Comparator, typename First, typename ... Args,
          typename = std::enable_if<are_same<First, Args...>::value, void>,
          typename = void>
//........^^^^^^^^^^^
typename = std::enable_if_t<are_same<First, Args...>::value, void>
// ......................^^
typename = std::enable_if_t<are_same<First, Args...>::value>
First min(First first, Args... args)