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++ VS2013上的SFINAE错误?_C++_Templates_C++11_Sfinae_Visual Studio 2013 - Fatal编程技术网

C++ VS2013上的SFINAE错误?

C++ VS2013上的SFINAE错误?,c++,templates,c++11,sfinae,visual-studio-2013,C++,Templates,C++11,Sfinae,Visual Studio 2013,我一直在尝试我能想到的任何方法,以使\u callWithRightMosTargetSinner函数正确失败,从而使SFINAE能够正常工作。通过这次尝试,VS2013给了我错误: 错误C2039:“type”:不是“std::enable\u if”的成员 有什么想法吗?有没有更好的选择?这里的想法是,我想对函数进行函数调用,前提是该函数采用NumArgs表示的数字或参数。最后两个可变参数应转发给函数并返回结果 template <typename Function, int NumA

我一直在尝试我能想到的任何方法,以使
\u callWithRightMosTargetSinner
函数正确失败,从而使SFINAE能够正常工作。通过这次尝试,VS2013给了我错误:
错误C2039:“type”:不是“std::enable\u if”的成员

有什么想法吗?有没有更好的选择?这里的想法是,我想对函数进行函数调用,前提是该函数采用NumArgs表示的数字或参数。最后两个可变参数应转发给函数并返回结果

template <typename Function, int NumArgs>
class SplitParameters {
public:
    typedef typename function_traits<Function>::result_type result_type;

    template <typename ... RightArgs>
    static result_type CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
        static_assert(sizeof...(RightArgs) >= NumArgs, "Unable to make function call with fewer than minimum arguments.");
        return _CallWithRightmostArgs(call, std::forward<RightArgs>(rightArgs)...);
    }

private:
    template <typename ... RightArgs>
    static result_type _CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
        return _CallWithRightmostArgsInner(call, std::forward<RightArgs>(rightArgs)...);
    }

    // note the '==' vs '!=' in these two functions.  I would assume that only one could exist
    template <typename LeftArg, typename ... RightArgs, typename std::enable_if<sizeof...(RightArgs) != NumArgs>::type* = 0>
    static result_type _CallWithRightmostArgsInner(const Function& call, LeftArg, RightArgs && ... rightArgs) {
        return _CallWithRightmostArgs(call, std::forward<RightArgs>(rightArgs)...);
    }

    template <typename LeftArg, typename ... RightArgs, typename std::enable_if<sizeof...(RightArgs) == NumArgs>::type* = 0>
    static result_type _CallWithRightmostArgsInner(const Function& call, LeftArg, RightArgs && ... rightArgs) {
        return call(std::forward<RightArgs>(rightArgs)...);
    }
};
模板
类拆分参数{
公众:
typedef typename函数_traits::result_type result_type;
模板
静态结果\u类型调用WithRightMoStargs(常量函数和调用,RightArgs和…RightArgs){
static_assert(sizeof…(RightArgs)>=NumArgs,“无法使用少于最小参数进行函数调用”);
return _CallWithRightmostArgs(call,std::forward(rightArgs)…);
}
私人:
模板
静态结果类型调用WithRightMOSTARGS(常量函数和调用、RightArgs和…RightArgs){
return _callwithrightmosargsinner(call,std::forward(rightArgs)…);
}
//注意这两个函数中的“==”和“!=”,我假设只有一个函数存在
模板
静态结果类型调用WithRightMosTargetSinner(常量函数&调用、LeftArg、RightArgs&…RightArgs){
return _CallWithRightmostArgs(call,std::forward(rightArgs)…);
}
模板
静态结果类型调用WithRightMosTargetSinner(常量函数&调用、LeftArg、RightArgs&…RightArgs){
回传呼叫(std::forward(rightArgs)…);
}
};

我将您的代码更改为

    #include <iostream>

    template <class T>
    struct function_traits
    {
        typedef void result_type;
    };

    template <typename Function, int NumArgs>
    class SplitParameters {
    public:
        typedef typename function_traits<Function>::result_type result_type;

        template <typename ... RightArgs>
        static result_type CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
            static_assert(sizeof...(RightArgs) >= NumArgs, 
                          "Unable to make function call with fewer than minimum arguments.");
            return _CallWithRightmostArgs(call, std::forward<RightArgs>(rightArgs)...);
        }

    private:
        template <typename ... RightArgs>
        static result_type _CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
            return _CallWithRightmostArgsInner(call, std::forward<RightArgs>(rightArgs)...);
        }

        // note the '==' vs '!=' in these two functions.  I would assume that only one could exist
        template <typename LeftArg, typename ... RightArgs, class = typename std::enable_if<sizeof...(RightArgs) != NumArgs -1 >::type>
        static result_type _CallWithRightmostArgsInner(const Function& call, LeftArg, RightArgs && ... rightArgs) {
            return _CallWithRightmostArgsInner(call, std::forward<RightArgs>(rightArgs)...);
        }

        template <typename ... RightArgs, class = typename std::enable_if<sizeof...(RightArgs) == NumArgs>::type>
        static result_type _CallWithRightmostArgsInner(const Function& call, RightArgs && ... rightArgs) {
            return call(std::forward<RightArgs>(rightArgs)...);
        }
    };

    void f(int i, int j)
    {
        std::cout << i << ' ' << j << std::endl;
    }

    int main()
    {
        SplitParameters<decltype(f), 2>::CallWithRightmostArgs(f, 1, 2, 3, 4);
    }
这个小代码段本身编译得很好,但如果您这样做:

    std::array<int,4> a;
    f(a);

    g++ gives:
    test3.cpp: In function ‘int main()’:
    test3.cpp:9:8: error: no matching function for call to ‘f(std::array<int, 4ul>&)’
         f(a);
            ^
    test3.cpp:9:8: note: candidate is:
    test3.cpp:4:6: note: template<class T, int size> void f(const std::array<T, size>&)
     void f(const std::array<T,size>&){}
          ^
    test3.cpp:4:6: note:   template argument deduction/substitution failed:
    test3.cpp:9:8: note:   mismatched types ‘int’ and ‘#‘integer_cst’ not supported by dump_type#<type error>’
         f(a);
            ^
    test3.cpp:9:8: note:   ‘std::array<int, 4ul>’ is not derived from ‘const std::array<T, size>’
std::数组a;
f(a);
g++提供:
test3.cpp:在函数“int main()”中:
test3.cpp:9:8:错误:对“f(std::array&)”的调用没有匹配的函数
f(a);
^
测试3.cpp:9:8:注:候选人是:
test3.cpp:4:6:注意:模板void f(const std::array&)
void f(const std::array&){
^
test3.cpp:4:6:注意:模板参数推断/替换失败:
test3.cpp:9:8:注意:dump#u type#不支持不匹配的类型“int”和“#”integer_cst”
f(a);
^
test3.cpp:9:8:注意:“std::array”不是从“const std::array”派生的
问题是,我声明模板为
size
参数使用
int
,但编译器得到的是一个
std::size\t
,它与
int
不同,即使您可以很容易地在它们之间进行转换。

在上面的示例中,我甚至不能将
=0
替换为
=NULL
,因为这只是
0L
文本,我必须执行
=(void*)0
才能让编译器接受它(因为
enable_if::type
的默认类型是
void

下面是我在ideone上的几次尝试(使用GCC4.8),我遇到了相同的错误:;注意:在计算参数数量时,您不应忽略
LeftArg
,它应该是
LeftArg&&
,为了避免复制(即使忽略它),我在ideone版本中修补了这些问题。@MatthieuM。ref有一个很好的地方——我仔细检查了它,因为那个变量是未使用的。这似乎就是它。我希望我能解释一下为什么以前失败了,但是我对这个解决方案已经很满意了。还值得一提的是,不再需要使用_CallWithRightmostArgs,并将解决方案简化为三个函数。您是否知道为什么需要
class=typename enable_(如果需要)
,而不仅仅是
typename enable_(如果……
)?这取决于您的意思是
typename如果::type*=0,则启用\如果::type
类型名称,则启用\如果::type
。第二个没有正确命名模板参数,我认为第一个不起作用,因为编译器在匹配模板参数时没有进行任何类型转换(这可能有点不正确/措词不当)。如果::type*=(void*)0起作用,则使用
typename启用。
    std::array<int,4> a;
    f(a);

    g++ gives:
    test3.cpp: In function ‘int main()’:
    test3.cpp:9:8: error: no matching function for call to ‘f(std::array<int, 4ul>&)’
         f(a);
            ^
    test3.cpp:9:8: note: candidate is:
    test3.cpp:4:6: note: template<class T, int size> void f(const std::array<T, size>&)
     void f(const std::array<T,size>&){}
          ^
    test3.cpp:4:6: note:   template argument deduction/substitution failed:
    test3.cpp:9:8: note:   mismatched types ‘int’ and ‘#‘integer_cst’ not supported by dump_type#<type error>’
         f(a);
            ^
    test3.cpp:9:8: note:   ‘std::array<int, 4ul>’ is not derived from ‘const std::array<T, size>’