关于使用可变参数模板的c ++致命错误C1001

时间:2016-08-29 13:19:40

标签: c++ compiler-errors variadic

大家好。编译我的代码我遇到了下一个错误:
致命错误C1001:编译器中发生内部错误。

当我只将一个参数传递给“exec”函数时,一切正常。但是,当我传递多个参数时,它会发出错误。我分别使用vs 2015和visual c ++编译器。

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
//using namespace std;

template <class T>
void param_push_(T arg, char ** param) {
  sprintf(*param, "%15.15e", arg);
}

template <class T, class... args>
void param_push_(T first, args... args, char ** param) {
  static int param_No = 0;
  sprintf(param[param_No++], "%15.15e", first);
  param_push(args..., param[param_No]);
}

template <class ... param_types>
void exec(const char * command, const param_types& ...param_values) {

  int arg_count = sizeof...(param_values);
  char ** params = new char*[arg_count];
  for (int i = 0; i < arg_count; ++i) {
    params[i] = new char[22 * sizeof(char)];
  }

  param_push_(param_values..., params); //cast parameters to (char *)  

  for (int i = 0; i < arg_count; ++i) {
    delete[] params[i];
  }
  delete[] params;

}

int main()
{
  double e_restriction = 0.55300000000000000000124124;
  double M_restriction = 5;

  exec("SELECT \"M\",e from orbital WHERE e < $1::double precision AND \"M\" < $2::double precision", e_restriction,M_restriction);

  return 0;
}

3 个答案:

答案 0 :(得分:0)

这是尝试在gcc上编译此代码的输出:

12 : error: declaration of 'args ... args'
void param_push_(T first, args... args, char ** param) {
^
11 : error: shadows template parm 'class ... args'
template <class T, class... args>
^
/tmp/gcc-explorer-compiler116729-61-oaaqho/example.cpp: In function 'void param_push_(T, args ..., char**)':
12 : error: declaration of 'args ... args'
void param_push_(T first, args... args, char ** param) {
^
11 : error: shadows template parm 'class ... args'
template <class T, class... args>
^
/tmp/gcc-explorer-compiler116729-61-oaaqho/example.cpp: In instantiation of 'void exec(const char*, const param_types& ...) [with param_types = {double, double}]':
41 : required from here
27 : error: no matching function for call to 'param_push_(const double&, const double&, char**&)'
param_push_(param_values..., params); //cast parameters to (char *)
^
7 : note: candidate: template<class T> void param_push_(T, char**)
void param_push_(T arg, char ** param) {
^
7 : note: template argument deduction/substitution failed:
27 : note: cannot convert 'param_values#1' (type 'const double') to type 'char**'
param_push_(param_values..., params); //cast parameters to (char *)
^
12 : note: candidate: template<class T, class ... args> void param_push_(T, args ..., char**)
void param_push_(T first, args... args, char ** param) {
^
12 : note: template argument deduction/substitution failed:
27 : note: cannot convert 'param_values#1' (type 'const double') to type 'char**'
param_push_(param_values..., params); //cast parameters to (char *)
^
Compilation failed

你可能想重新考虑一下:

template <class T, class... Args>
void param_push_(T first, Args... args, char ** param) {

  //
  // WARNING: param_No will be a different variable for each
  // combination of Args...
  //
  static int param_No = 0;

  sprintf(param[param_No++], "%15.15e", first);
  param_push(args..., param[param_No]);
}

答案 1 :(得分:0)

这是一个新代码。模板函数不会改变当前参数。但它应该做,不是吗?

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
//using namespace std;

template <class T>
void param_push_(T arg, char ** param) {
  sprintf(*param, "%15.15e", arg);
}

template <class T, class... args>
void param_push_(T first, args... args_temp, char ** param) {
  static int param_No = 0;
  sprintf(param[param_No++], "%15.15e", first);
  param_push_(args_temp..., param[param_No]);
}

template <class ... param_types>
void my_exec(const char * command, const param_types& ...param_values) {

  int arg_count = sizeof...(param_values);
  char ** params = new char*[arg_count];
  for (int i = 0; i < arg_count; ++i) {
    params[i] = new char[22 * sizeof(char)];
  }

  param_push_(param_values..., params); //cast parameters to (char *)  

  for (int i = 0; i < arg_count; ++i) {
    delete[] params[i];
  }
  delete[] params;

}

int main()
{
  double e_restriction = 0.55300000000000000000124124;
  double M_restriction = 5;
  param_push_<double, double, char**>;
  my_exec("SELECT \"M\",e from orbital WHERE e < $1::double precision AND \"M\" < $2::double precision", 
    e_restriction, M_restriction);

    return 0;
}

答案 2 :(得分:0)

试试这个 - 它有效。

#include <stdio.h>
#include <iostream>

template <typename ...> struct param_push;

template <class H, class... T>
struct param_push<H,T...> {
   void operator() (H head, T... tail, char** param) {
     sprintf(param[0], "%15.15e", head);
     param_push<T...> one_less;
     one_less(tail..., &param[1]);
   }
};

template <>
struct param_push<> {
  void operator() (char** param) {
    // does nothing, no more args to sprintf
  }
};

template <class ... param_types>
void exec(const char * command, const param_types& ...param_values) {

  int arg_count = sizeof...(param_values);
  char ** params = new char*[arg_count];
  for (int i = 0; i < arg_count; ++i) {
    params[i] = new char[22 * sizeof(char)];
  }

  // param_push_(param_values..., params); //cast parameters to (char *)
  struct param_push<param_types...> functor;
  functor(param_values..., params);

  for (int i = 0; i < arg_count; ++i) {
    std::cout << params[i] << " will be deleted" << std::endl;
    delete[] params[i];
  }
  delete[] params;

}

int main()
{
  double e_restriction = 0.55300000000000000000124124;
  double M_restriction = 5;

  exec("SELECT \"M\",e from orbital WHERE e < $1::double precision AND \"M\" < $2::double precision", e_restriction,M_restriction);

  return 0;
}

(现在,Arty Zefirov的作业:找到使用模板结构函子的原因,这个技术有效,为什么它不能用于模板化函数,并用结果更新你的问题)