使用模板模板参数时推导数组的大小

问题描述 投票:0回答:3

以下讨论中显示了一种查找模板数组中元素数量的非常简单的方法:

这个函数模板是如何推导出数组的大小的?

我想模拟相同的方法来获取模板模板数组中的元素数量:

//classA.h

#include <type_traits>
#include <cstddef>
#include <iostream>

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

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

template<template<typename T>class A, size_t N>
size_t cal_size(A<T>*&[N]){
 return N;
}

template<typename T>
class A{
  public:
  A(T);
  private:
  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;
}


#include "classA.h"

int main (){
 
 array2As<int> a = {A(5),A(7)};
 auto sz = cal_size(a); 
 array2As<double> b = {A(1.2),A(6.3)};
 auto sz = cal_size(b); 

 return 0;
}

对于上面的代码,我得到以下编译器错误:

In file included from main.cpp:1:
classA.h:18:19: error: ‘T’ was not declared in this scope
   18 | size_t cal_size(A<T>*&[N]){
      |                   ^
compilation terminated due to -Wfatal-errors.

为什么我会收到此错误?

c++ arrays size template-templates
3个回答
3
投票

T
中的
template <typename T> class A
并没有介绍
T
。它未使用。你必须介绍一下
typename T

应该是

template <template <typename> class A, typename T, size_t N>
size_t cal_size(const A<T>(&)[N]){
     return N;
}

演示


0
投票

模板模板参数需要在模板模板参数列表中引入:

template <template <typename> class A, class T, size_t N>
// no name needed   ^^^^^^^^           ^^^^^^^ this is needed
constexpr size_t cal_size(A<T>(&)[N]) {
    return N;
}

0
投票

模板参数中的参数名称在您的情况下没有用。 参数中:

template<typename T> class A

...

typename T
引入了名称
T
,但仅限于尖括号的范围内。
T
仅在
template<...>
内部可见,在其外部不可见。另请参阅命名参数到模板模板参数中是否有任何用途。 无法从
A<T>
推断出它,因为该名称不存在于该范围内。

正如@Jarod42所说,你可以

template <template <typename> class A, typename T, size_t N>

但这比使用您链接的问题中的函数没有任何优势。 请注意,C++17 引入了

std::size
,其工作方式与链接函数完全相同:

std::size_t sz = std::size(a); 

注意:

A
模板模板参数和
A
类模板不一定相同。他们只是巧合地共用一个名字。

© www.soinside.com 2019 - 2024. All rights reserved.