C++ 传递可变模板参数时发生Visual studio错误

C++ 传递可变模板参数时发生Visual studio错误,c++,visual-studio,c++11,visual-studio-2015,variadic-templates,C++,Visual Studio,C++11,Visual Studio 2015,Variadic Templates,我有一个模板函数,它具有数量可变的模板参数,这些参数“中继”到std::function参数: template<typename... Args> void test1(const std::function<void(Args...)> &function) {} static void t(float) {} int main(int argc,char *argv[]) { test1<float>(nullptr);

我有一个模板函数,它具有数量可变的模板参数,这些参数“中继”到std::function参数:

template<typename... Args>
    void test1(const std::function<void(Args...)> &function)
{}

static void t(float) {}

int main(int argc,char *argv[])
{
    test1<float>(nullptr);
    test1<float>(&t);
    test1<float>([](float f) -> void {

    });
    return EXIT_SUCCESS;
}
模板
void test1(const std::function&function)
{}
静态空隙t(浮点数){}
int main(int argc,char*argv[])
{
test1(nullptr);
测试1&t;
test1([](float f)->void{
});
返回退出成功;
}
这可以很好地编译和运行,但visual studio在main中的所有test1调用下划红色下划线,并显示以下错误消息:

template<class... Args> void test1(const std::function<void(Args...)> &function)

no instance of function template "test1" matches the argument list
    argument types are: (lambda []void(float f)->void)
模板无效测试1(const std::function&function)
没有函数模板“test1”的实例与参数列表匹配
参数类型为:(lambda[]void(float f)->void)
另一方面,这不会显示为错误:

template<typename... Args>
    void test2(Args... a)
{}
int main(int argc,char *argv[])
{
    test2<float>(1.f);
    return EXIT_SUCCESS;
}
模板
无效测试2(Args…a)
{}
int main(int argc,char*argv[])
{
试验2(1.f);
返回退出成功;
}
我是否在第一个病例中做了不正确的事情,或者这是假阳性?这只是VisualStudio本身的一个错误,编译器甚至不会抛出任何警告

//编辑:

我刚刚用g++-5在Linux上做了一些测试,它根本不允许我编译代码:

root@******:/var/projects# g++-5 -std=c++1y test.cpp
test.cpp: In function ‘int main(int, char**)’:
test.cpp:12:22: error: no matching function for call to ‘test1(std::nullptr_t)’
  test1<float>(nullptr);
                      ^
test.cpp:5:7: note: candidate: template<class ... Args> void test1(const std::function<void(Args ...)>&)
  void test1(const std::function<void(Args...)> &function)
       ^
test.cpp:5:7: note:   template argument deduction/substitution failed:
test.cpp:12:22: note:   mismatched types ‘const std::function<void(Args ...)>’ and ‘std::nullptr_t’
  test1<float>(nullptr);
                      ^
test.cpp:13:17: error: no matching function for call to ‘test1(void (*)(float))’
  test1<float>(&t);
                 ^
test.cpp:5:7: note: candidate: template<class ... Args> void test1(const std::function<void(Args ...)>&)
  void test1(const std::function<void(Args...)> &function)
       ^
test.cpp:5:7: note:   template argument deduction/substitution failed:
test.cpp:13:17: note:   mismatched types ‘const std::function<void(Args ...)>’ and ‘void (*)(float)’
  test1<float>(&t);
                 ^
test.cpp:16:3: error: no matching function for call to ‘test1(main(int, char**)::<lambda(float)>)’
  });
   ^
test.cpp:5:7: note: candidate: template<class ... Args> void test1(const std::function<void(Args ...)>&)
  void test1(const std::function<void(Args...)> &function)
       ^
test.cpp:5:7: note:   template argument deduction/substitution failed:
test.cpp:16:3: note:   ‘main(int, char**)::<lambda(float)>’ is not derived from ‘const std::function<void(Args ...)>’
  });
   ^
root@******:/var/projects#g++-5-std=c++1y test.cpp
test.cpp:在函数“int main(int,char**)”中:
test.cpp:12:22:错误:调用“test1(std::nullptr_t)”时没有匹配的函数
test1(nullptr);
^
test.cpp:5:7:注:候选:模板void test1(const std::function&)
void test1(const std::function&function)
^
test.cpp:5:7:注意:模板参数扣除/替换失败:
test.cpp:12:22:注意:类型“const std::function”和“std::nullptr\t”不匹配
test1(nullptr);
^
test.cpp:13:17:错误:调用“test1(void(*)(float))”时没有匹配的函数
测试1&t;
^
test.cpp:5:7:注:候选:模板void test1(const std::function&)
void test1(const std::function&function)
^
test.cpp:5:7:注意:模板参数扣除/替换失败:
test.cpp:13:17:注意:类型“const std::function”和“void(*)(float)”不匹配
测试1&t;
^
test.cpp:16:3:错误:调用“test1(main(int,char**)::)时没有匹配的函数”
});
^
test.cpp:5:7:注:候选:模板void test1(const std::function&)
void test1(const std::function&function)
^
test.cpp:5:7:注意:模板参数扣除/替换失败:
test.cpp:16:3:注意:“main(int,char**):”不是从“const std::function”派生的
});
^

visual studio解析稍微落后于编译器,并单独实现。可变模板对于VisualStudio来说还是很新的,所以它可能是一个已知的限制/缺陷

更新:

即使使用最新版本的clang,我也不清楚到底发生了什么: 因为您已将
Args…
修复为``float`,但相应的非模板代码不会编译

此外,如果您将
Args…
更改为
Args
,它也会起作用。我不清楚为什么

更新2:我发现你的问题是重复的,答案很好:


草率的摘要:当您编写
test2
时,它或多或少意味着
test2
,这阻碍了进一步的转换。

要解决此问题并使程序按预期工作,您可以将测试函数包装在模板结构中:

template<typename... Args>
struct foo {
   static void test1(const std::function<void(Args...)> &function) {}
};
模板
结构foo{
静态void test1(const std::function&function){}
};
并称之为:

foo<float>::test1(nullptr);
foo<float>::test1(&t);
foo<float>::test1([](float f) -> void {

});
foo::test1(nullptr);
foo::test1&t;
foo::test1([](float f)->void{
});

它肯定会阻止您的
Args…
被推断出来。

看起来不仅仅限于visual studio(请参见我的编辑)。