中继可变参数模板参数时出现 Visual Studio 错误 [重复]

Posted

技术标签:

【中文标题】中继可变参数模板参数时出现 Visual Studio 错误 [重复]【英文标题】:Visual studio error when relaying variadic template parameters [duplicate] 【发布时间】:2016-07-16 14:24:42 【问题描述】:

我有一个模板函数,其模板参数数量可变,它们“中继”到 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;

这编译并运行良好,但 Visual Studio 将 maintest1 中的 all 调用标记为红色,并带有以下错误消息:

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)

另一方面,这不会显示为错误:

template<typename... Args>
    void test2(Args... a)

int main(int argc,char *argv[])

    test2<float>(1.f);
    return EXIT_SUCCESS;

我在第一种情况下做错了什么还是误报?这只是 Visual Studio 本身的错误,编译器甚至不会抛出任何警告。

// 编辑:

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

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 ...)>’
  );
   ^

【问题讨论】:

【参考方案1】:

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

template<typename... Args>
struct foo 
   static void test1(const std::function<void(Args...)> &function) 
;

并称它为:

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

);

绝对可以防止你的Args...被推导出来。

【讨论】:

【参考方案2】:

Visual Studio 解析有点落后于编译器,并且是单独实现的。可变参数模板对于 Visual Studio 来说还是很新的东西,所以它可能是一个已知的限制/错误。

更新:

即使使用最新版本的 clang,我也不清楚发生了什么: live example 因为您确实将 Args... 修复为 ``float` 但相应的非模板代码确实可以编译。

此外,如果您将Args... 更改为Args,它确实有效。我不清楚为什么...

更新 2:我发现您的问题是重复的,答案很好: variadic templates parameter matching in std::function

草率的总结:当你写test2&lt;float&gt;时,它或多或少意味着test2&lt;float,Args...&gt;,这会阻碍进一步的转换。

【讨论】:

看起来它不仅限于视觉工作室(见我的编辑)。

以上是关于中继可变参数模板参数时出现 Visual Studio 错误 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

解压可变参数模板的结果 - Visual Studio 2019 CE

扩展 Ordering 以容纳类对象时出现 PriorityQueue 可变参数错误

Eclipse CDT - 使用模板默认值时出现“无效参数”

[C++11 模板的改进] --- 可变参数模板

可变参数模板类:是不是可以为每个可变参数模板参数实现一个唯一的成员函数?

如何使用可变参数模板参数保存可变数量的参数?