Visual Studio 2017-无法推断模板参数(带有可变参数模板) [英] Visual Studio 2017 - could not deduce template argument (with variadic templates)

查看:70
本文介绍了Visual Studio 2017-无法推断模板参数(带有可变参数模板)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码可在gcc和clang中编译并正常工作,但无法在Visual Studio 2017.7(x86-64)中编译:

The following code compiles and works fine in gcc and clang, but fails to compile in Visual Studio 2017.7 (x86-64):

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


template <template <typename...> class>
struct isVector : public std::false_type
{ };

template <>
struct isVector<std::vector> : public std::true_type
{ };

// Other isVector specializations (for QVector<T>, etc...)
// ...


// A function accepting vector<vector<double>>
template <
    template<typename ...> class V1,
    template<typename ...> class V2 >
auto loadData(V1<V2<double>> & v, std::string fn)
-> std::enable_if_t<isVector<V1>::value && isVector<V2>::value>
{
    std::cout << "- vector of vector version, " << fn << std::endl;
}

// A function accepting vector<double>
template <
    template<typename ...> class V >
auto loadData(V<double> & v, std::string fn)
-> std::enable_if_t<isVector<V>::value>
{
    std::cout << "- vector version, " << fn << std::endl;

    V<V<double>> vv({ v });

    loadData(vv, fn);
}

// Other loadData() function specializations and overloads
// ...


int main()
{
    std::vector<double> vd;
    std::vector<std::vector<double>> vvd;

    loadData(vd, "case  1");
    loadData(vvd, "case  2");

    return 0;
}

这是错误消息:

<source>(50): error C2672: 'loadData': no matching overloaded function found
<source>(50): error C2784: 'enable_if<_Test,_Ty>::type loadData(V<double> &,std::string)': could not deduce template argument for 'V<double> &' from 'std::vector<double,std::allocator<_Ty>>'
        with
        [
            _Ty=void
        ]
        and
        [
            _Ty=double
        ]
<source>(31): note: see declaration of 'loadData'
<source>(50): error C2782: 'enable_if<_Test,_Ty>::type loadData(V<double> &,std::string)': template parameter 'V' is ambiguous
        with
        [
            _Ty=void
        ]
<source>(31): note: see declaration of 'loadData'
<source>(50): note: could be 'std::_Vector_alloc'
<source>(50): note: or       'std::vector'
<source>(50): error C2784: 'enable_if<_Test,_Ty>::type loadData(V1<V2<double>> &,std::string)': could not deduce template argument for 'V1<V2<double>> &' from 'std::vector<double,std::allocator<_Ty>>'
        with
        [
            _Ty=void
        ]
        and
        [
            _Ty=double
        ]
<source>(22): note: see declaration of 'loadData'
<source>(50): error C2782: 'enable_if<_Test,_Ty>::type loadData(V1<V2<double>> &,std::string)': template parameter 'V1' is ambiguous
        with
        [
            _Ty=void
        ]
<source>(22): note: see declaration of 'loadData'
<source>(50): note: could be 'std::_Vector_alloc'
<source>(50): note: or       'std::vector'
<source>(51): error C2672: 'loadData': no matching overloaded function found
<source>(51): error C2784: 'enable_if<_Test,_Ty>::type loadData(V<double> &,std::string)': could not deduce template argument for 'V<double> &' from 'std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>'
        with
        [
            _Ty=void
        ]
        and
        [
            _Ty=double
        ]
<source>(31): note: see declaration of 'loadData'
<source>(51): error C2782: 'enable_if<_Test,_Ty>::type loadData(V<double> &,std::string)': template parameter 'V' is ambiguous
        with
        [
            _Ty=void
        ]
<source>(31): note: see declaration of 'loadData'
<source>(51): note: could be 'std::_Vector_alloc'
<source>(51): note: or       'std::vector'
<source>(51): error C2784: 'enable_if<_Test,_Ty>::type loadData(V1<V2<double>> &,std::string)': could not deduce template argument for 'V1<V2<double>> &' from 'std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>'
        with
        [
            _Ty=void
        ]
        and
        [
            _Ty=double
        ]
<source>(22): note: see declaration of 'loadData'
<source>(51): error C2782: 'enable_if<_Test,_Ty>::type loadData(V1<V2<double>> &,std::string)': template parameter 'V2' is ambiguous
        with
        [
            _Ty=void
        ]
<source>(22): note: see declaration of 'loadData'
<source>(51): note: could be 'std::_Vector_alloc'
<source>(51): note: or       'std::vector'

这是VS还是代码错误?关于如何解决它的任何建议?我确实尝试过使用/permissive-/std:latest 进行编译,没有任何区别.

Is this a VS or a code bug? Any suggestions on how to fix it? I did try compiling with /permissive- and /std:latest, didn't make a difference.

此处接受的答案中建议了原始代码:同时接受std :: vector和QVector的功能模板吗?

The original code was suggested in the accepted answer here: A function template that accepts both std::vector and QVector?

编译器资源管理器链接: https://godbolt.org/g/by7nBM

Compiler explorer link: https://godbolt.org/g/by7nBM

谢谢!

推荐答案

我也遇到了这个讨厌的小错误.我认为这也是一个错误.以下代码曾经在以前的版本下运行:

I too have bumped into this nasty little bug. I think it's a bug as well. The following code used to work under previous versions:

namespace Catch {
    template<typename Ty_, typename... Args_>
    std::string Tags(Ty_ x, Args_... others) {
        return Tags(x) + Tags(others...);
    }
}

依此类推,将很有用,如下所示:

And so on, and would be useful as follows:

TEST_CASE("my test case", Catch::Tags("one", "two", "fred", "red")) {
    // ...
}

使用 Catch2 ,不确定是否需要添加 .c_str();至少在 Catch 中,我认为这是必要的.也许不再那么重要了.

With Catch2, not sure if you need to append an .c_str() on that; at least in Catch, I think that was necessary. Perhaps not so much any more.

我这样做是为了避免陷入标签语法的麻烦,我可以只关注标签本身,而保留可变参数函数的样板语法.

I did this in an effort to keep from having to trip up over tag syntax, and I could simply focus on the tags themselves and leave the boilerplate syntax for the variadic functions.

但是...现在我已经犯了这个编译器错误.

However... Now I've run afoul of this compiler bug.

任何想法,如果有 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆