首页 > 解决方案 > 编译器对模板的无效实例化给出错误

问题描述

#include<iostream>
template<typename T,  typename... Rest>
void printf_vt( const char *s, T value,Rest... rest)
{
    
 while (*s) {
    if (*s == '%' && *(++s) != '%') {
        std::cout << value;
        printf_vt(s, rest...); //called even when *s is 0,
        return; //but does nothing in that case
    }
    std::cout << *s++;
 }
}

int main() {
 int x = 10;
 float y = 3.6;
 const char* msg2 = "can accept % parameters (or %); x=%,y=%\n";
 printf_vt(msg2, 100, "more",x,y);
 return 0;
}

模仿“C”printf函数的程序(与问题无关)。

错误:

t1.cpp: In instantiation of 'void printf_vt(const char*, T, Rest ...) [with T = float; Rest = {}]':
t1.cpp:281:12:   recursively required from 'void printf_vt(const char*, T, Rest ...) [with T = const char*; Rest = {int, float}]'
t1.cpp:281:12:   required from 'void printf_vt(const char*, T, Rest ...) [with T = int; Rest = {const char*, int, float}]'
t1.cpp:293:11:   required from here
t1.cpp:281:26: error: no matching function for call to 'printf_vt(const char*&)'
  281 |                 printf_vt(s, rest...); //called even when *s is 0,
      |                 ~~~~~~~~~^~~~~~~~~~~~
t1.cpp:275:6: note: candidate: 'template<class T, class ... Rest> void printf_vt(const char*, T, Rest ...)'
  275 | void printf_vt( const char *s, T value,Rest... rest)
      |      ^~~~~~~~~
t1.cpp:275:6: note:   template argument deduction/substitution failed:
t1.cpp:281:26: note:   candidate expects at least 2 arguments, 1 provided
  281 |                 printf_vt(s, rest...); 
      |                 ~~~~~~~~~^~~~~~~~~~~~

问题是编译器正在尝试使用创建模板函数

Rest = {int , const char*, int , float}  //{100 , "more" , x , y}

为什么这样做?当有 2 个必需参数时,编译器不应将100其用于可变参数。

它还会尝试使用创建模板功能Rest = {const char* , int , const char* ,int , float}吗?

代码是否有任何错误,或者这不是使用可变参数的方式?

编译器 g++ 11.1.0(也给出了与 clang 相同的错误)

标签: c++templatesrecursion

解决方案


问题是,在最后的递归调用中,对于;rest变为空。printf_vt(s, rest...);并且没有候选人printf_vt被召唤。

您可以添加一个重载printf_vtconst char *匹配上述场景,它也有望终止递归调用。例如

void printf_vt(const char *s)
{
    std::cout << s;
}

居住


推荐阅读