声明一个带有 void return 的模板函数,采用 typedef

declaring a template function with void return taking a typedef

提问人:Vinod 提问时间:9/9/2023 最后编辑:Vinod 更新时间:9/10/2023 访问量:53

问:

我已经查看了大多数相关帖子,但找不到与我的特定使用场景相关的回复。

代码如下图所示:

//classA.h file

#include <type_traits>
#include <iostream>

using std::is_same;
using std::cout;
using std::endl;

template<typename T> class A;
template<typename T>
using array2As = A<T>[2];

template<typename T> 
void doSomething(array2As);

template<typename T>
class A{
  public:
  A(T);
  private:
  friend void doSomething(array2As);
  A()=delete;
  A(const A&)=delete; 
  A& operator=(const A&)=delete;
  T elem;
};

template<typename T>
A<T>::A(T elem){
  static_assert(is_same<T,int>::value || is_same<T,double>::value, "Compilation error: type must be int or double");
  this.elem = elem;
}

template<typename T> void doSomething(array2As a){
  if(is_same<T,int>::value){ auto sz = sizeof(a)/sizeof(int);}
  else{auto sz = sizeof(a)/sizeof(double);}
  static_assert(2 == sz, "Compilation error: array must have exactly 2 elements");
 
  for(auto i=0; i<sizeof(a);++i){
   auto T& = a[i];
   cout << T.elem << endl;
 }

 return;
}

上面的代码没有编译,但你可以看到我打算做什么。我希望为同一模板类类型的两个实例的数组创建一个类型定义,然后在我的函数模板的声明中使用该类型定义。函数模板本身应该是模板类类型的友元函数。

我收到以下代码行的编译错误(由于以下原因,编译不会继续进行):-Wfatal-errors

template<typename T> void doSomething(array2As);

错误是

error: variable or field 'doSomething' declared void

基于此错误,我认为编译器无法将 的类型定义与类型相关联。arra2AsT

那么如何才能做到这一点呢?

TIA系列

附言:

代码如下:main.cpp

#include "classA.h"

int main (){
 
 array2As a = {A(5),A(7)};
 doSomething(a);
 array2As b = {A(1.2),A(6.3)};
 doSomething(b);

 return 0;
}
C++ 函数模板

评论

0赞 user17732522 9/9/2023
friend doSomething<>(array2As);只是缺少返回类型,并且到处都缺少模板参数列表。但是,它仍然行不通。函数参数中的数组类型被剥离其大小,并转换为指向元素类型的指针。要么使用,要么使用,而不是按引用传递。voidarray2As<T>std::array
0赞 user17732522 9/9/2023
并且没有给你数组大小......鉴于这是一个非常基本的误用,似乎与其余代码的级别无关,也许还有其他问题。我没有详细检查代码。sizeof(a)
0赞 Vinod 9/9/2023
@user17732522感谢您指出朋友声明中关于虚空的遗漏......但是,我不明白为什么我应该使用 arra2As<T>,因为 array2As 本身是根据 A<T> 定义的?
0赞 Vinod 9/9/2023
@user17732522同意sizeof()是一个错误......
0赞 user17732522 9/9/2023
array2As本身就是一个模板,就像一个是一样。如果你想要一个专业化,你需要像任何其他模板一样给它模板参数。或者你如何期望编译器在你写作时知道你的意思是(即)还是(即)等?Aarray2As<int>A<int>[2]array2As<double>A<double>[2]array2As

答:

0赞 Remy Lebeau 9/9/2023 #1

array2As是一个模板,因此您必须在使用它的任何位置指定其模板参数(除非在编译器能够为您推断它的地方,例如在您的 中)。main()

例如:

template<typename T> void doSomething(array2As);

需要:

template<typename T> void doSomething(array2As<T>);

和:

friend doSomething<>(array2As);

需要:

friend doSomething<T>(array2As<T>);

和:

template<typename T> void doSomething<T>(array2As a)

需要:

template<typename T> void doSomething<T>(array2As<T> a)

评论

0赞 Vinod 9/9/2023
在从朋友声明中省略类型 T 之前,我指的是这个链接 isocpp.org/wiki/faq/templates#template-friends......