【问题标题】:function template specialization - error - ISO C++ forbids declaration of ‘parameter’ with no type函数模板专业化 - 错误 - ISO C++ 禁止声明没有类型的“参数”
【发布时间】:2019-08-11 15:27:20
【问题描述】:

这是示例代码(Forouzan 和 Gilberg 的 C++ Programming: An Object-Oriented Approach 第 700 页。

据我了解,这是为了解释function template specialization,我已经阅读并看到很多人说要避免这种情况而支持overloadingtraits class(不管是什么),我想还有其他方法-所以我不打算花太多时间在上面,但我想学习它。 @Roger Pate 提供了一个我仍在吸收的好链接的答案(在下面类似问题的链接中):http://www.gotw.ca/publications/mill17.htm

 1 #include <iostream>
 2 #include <string>
 3 #include <cstring>
 4 using namespace std;
 5
 6 // Template Function
 7 template <typename T> 
 8 T smaller(const T& first, const T& second)
 9 {
10         if (first < second)
11         {
12                 return first;
13         }
14         return second;
15 }
16
17 // Specialization of template function (previously defined)
18 // a C-style string is of type: const char* 
19 // so replace every "T" with that
20 template <> 
21 const char* smaller (const (const char*) & first, const (const char*) & second)
22 //const char* smaller<>(const (const char*)& first, const (const char*)& second)
23 //const char* smaller<const char*>(const (const char*)& first, const (const char*)& second)
24 {
25         if (strcmp (first, second ) < 0)
26         {
27                 return first;
28         }
29         return second;
30 }
31
32 int main ( )
33 {
34
35         // Calling template with two string objects
36         string str1 = "Hello";
37         string str2 = "Hi";
38         cout << "Smaller (Hello , Hi): " << smaller (str1, str2) << endl;
39
40         //Calling template function with two C-string objects
41         const char* s1 = "Bye";
42         const char* s2 = "Bye Bye";
43         cout << "Smaller (Bye, Bye Bye)" << smaller (s1, s2) << endl;
44 //      cout << "Smaller (Bye, Bye Bye)" << smaller<>(s1, s2) << endl;
45 //      cout << "Smaller (Bye, Bye Bye)" << smaller<const char*>(s1, s2) << endl;
46
47         return 0;
48 }
49
50
51 /*
52 The operator < is not defined for a C-style string, meaning we cannot use the template
53 function to find the smaller of the two C-style strings.
54 This operator is defined in the library "string", and so overloads the operator
55 */

相同的代码,没有行号和我的失败尝试:

/***************************************************************
* Template function definition with specialization *
***************************************************************/
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

// Template Function
template <typename T>
T smaller (const T& first, const T& second)
{
  if (first < second)
  {
    return first;
  }
  return second;
}

// Specialization of template function
template <>
const char* smaller (const (const char*) & first, const (const char*) & second)
{
  if (strcmp (first, second ) < 0)
  {
    return first;
  }
  return second;
}

int main ( )
{
  // Calling template with two string objects
  string str1 = "Hello";
  string str2 = "Hi";
  cout << "Smaller (Hello , Hi): " << smaller (str1, str2) << endl;

  //Calling template function with two C-string objects
  const char* s1 = "Bye";
  const char* s2 = "Bye Bye";
  cout << "Smaller (Bye, Bye Bye)" << smaller (s1, s2) << endl;

  return 0;
}

长话短说,我的编译器gcc-8

2120|1|root@sbh ~/CODING/CppTemplate # Sun 11 08 2019, 08:53:15 
 /usr/bin/gcc-8 --version
gcc-8 (Debian 8.3.0-19) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

无论我尝试如何修复(如下),都会始终抛出此输出。

2122|1|root@sbh ~/CODING/CppTemplate # Sun 11 08 2019, 08:56:33 
 g++-8 -Wall -O -std=c++2a templateSpecialization.cpp -o templateSpecialization.out 
templateSpecialization.cpp:21:42: error: ISO C++ forbids declaration of ‘parameter’ with no type [-fpermissive]
 const char* smaller (const (const char*) & first, const (const char*) & second)
                                          ^
templateSpecialization.cpp:21:44: error: expected ‘,’ or ‘...’ before ‘first’
 const char* smaller (const (const char*) & first, const (const char*) & second)
                                            ^~~~~
templateSpecialization.cpp:21:13: error: template-id ‘smaller<>’ for ‘const char* smaller(const int (*)(const char*))’ does not match any template declaration
 const char* smaller (const (const char*) & first, const (const char*) & second)
             ^~~~~~~
templateSpecialization.cpp:8:3: note: candidate is: ‘template<class T> T smaller(const T&, const T&)’
 T smaller(const T& first, const T& second)
   ^~~~~~~

我注意到这个问题,它的答案具有相同的功能精神,Function template specialization importance and necessity by https://stackoverflow.com/users/124797/jagannath @jagannath ;

template<typename T>
bool Less(T a, T b)
{
    cout << "version 1 ";
    return a < b;
}
// Function templates can't be partially specialized they can overload instead.
template<typename T>
bool Less(T* a, T* b)
{
    cout << "version 2 ";
    return *a < *b;
}

template<>
bool Less<>(const char* lhs, const char* rhs)
{
    cout << "version 3 ";
    return strcmp(lhs, rhs) < 0;
}

int a = 5, b = 6;

cout << Less<int>(a, b) << endl;
cout << Less<int>(&a, &b) << endl;
cout << Less("abc", "def") << endl;

看来我正在对我的function template 进行所有相同的修改,例如例如,将每个“T”替换为“const char*”,第 22 和 23 行。

我阅读了一些关于编译器“推断”使用什么的信息,因此我尝试在调用中在函数名称之后添加括号(第 44 和 45 行)。

我确定这很简单,可能在其他地方也有介绍,但我找不到。甚至可能是在类模板的上下文中的解释,但我刚刚开始学习模板,这就是我所得到的(即那本书中的第 700 页)。

即使这个问题Function Template Specialization Error 似乎也有类似的问题does not match any template declaration 但我觉得我已经遵循了这种模式,如第 21 行(作者的)和我的第 22 行和第 23 行。

PS: 我认为这无关紧要,但我的环境可能有点奇怪......

【问题讨论】:

  • 如果您对模板的实例化方式感到好奇,通常可以通过instantiate it and look at the generated symbol 来帮助您。
  • 不错的平台 - 就像一个超级 objdump - 不知道它,它使用 type_traits
  • 是的,它基本上可以编译并显示您提供给它的任何代码的程序集。该网站也有很多可用的编译器,有时会很有帮助。

标签: c++ function templates generic-programming


【解决方案1】:

尝试将类型定义为:

template <>
const char* smaller (const char* const &first , const char* const &second);

或者:

using cstring_t = const char*;
template <>
const char* smaller (const cstring_t& first, const cstring_t& second);

对于第一种情况,const char* const &amp;,如果您使用“east const”表示法:

char const * const &

您可以从右到左阅读:“引用一个常量指针,指向一个常量字符”。不需要括号。

如果您不想与类型混淆,第二个示例显示了一个更简洁的示例。两个函数签名都解析为相同的类型。

【讨论】:

  • 哦,谢谢 - 它成功了!我想知道为什么作者的例子不起作用……看起来很奇怪……
  • 在第一个示例中,通过放置这些括号,编译器认为您正在尝试使用函数类型 &lt;return type&gt; (&lt;parameters&gt;) 作为参数。但是,由于const 不是类型,它告诉参数函数需要返回类型。
  • 所以括号有最好的优先级;)我现在注意到我的第 44 行和第 45 行也有效。
  • 我相信优先级与Most vexing parse类似:如果某些带括号的表达式不明确,则作为函数声明消除歧义。
猜你喜欢
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 2015-10-31
相关资源
最近更新 更多