正确获取模板模板函数声明正确

Getting templated template function declaration correct

本文关键字:声明 函数 获取      更新时间:2023-10-16

我有这样的问题,我正在尝试进行编译:

#include <vector>
#include <array>
struct Test
{
    template <template <typename...> class Container, typename T, typename... Args>
    void SetData(const Container<T, Args...>& data)
    {
        // compiles for vector but not array
        // 'void Test::SetData(const Container<T,Args...> &)': could not deduce template argument for 'const Container<T,Args...> &' from 'std::array<float,3>' 
    }
};

int main()
{
    Test test;
    std::vector<int> vector{ 1,2,3 };
    std::array<float, 3> arr{1.0f, 2.0f, 3.0f};
    test.SetData(vector);
    test.SetData(arr);
    return 0;
}

本质上,我需要一个功能签名,该功能签名可以接受任何arbitary STL容器(更具体地说是std::vectorstd::array),并且我还需要该功能中可见的T类型(在这种情况下为intfloat)。我不在乎的其他类型(分配器或std::array大小)。

什么是正确的签名?

什么是正确的签名?

我知道,不可能编写一个正确的签名来拦截所有容器和仅容器。

但是,如果您接受编写类型特征,说明类型是否为容器并提取包含的类型(需要通用版本,std::vector的部分专业化和类似的typename ...容器以及std::array的专业化;其他专业化也可以是添加)作为以下isCnt

template <typename>
struct isCnt : public std::false_type
 { };
// std::array case
template <template <typename, std::size_t> class C,
          typename T, std::size_t N >
struct isCnt<C<T, N>> : public std::true_type
 { using containedType = T; };
// other container case
template <template <typename ...> class C,
          typename T0, typename ... Ts>
struct isCnt<C<T0, Ts...>> : public std::true_type
 { using containedType = T0; };

您可以如下构建setData()

template :: containedType> void setData(c const&amp;数据) { //在这里代码 }

观察setData()是由T = isCnt<C>::containedType启用Sfinae(或禁用),仅适用于容器。

以下是一个完整的工作示例

#include <array>
#include <vector>
#include <iostream>
#include <type_traits>
template <typename>
struct isCnt : public std::false_type
 { };
// std::array case
template <template <typename, std::size_t> class C,
          typename T, std::size_t N >
struct isCnt<C<T, N>> : public std::true_type
 { using containedType = T; };
// other container case
template <template <typename ...> class C,
          typename T0, typename ... Ts>
struct isCnt<C<T0, Ts...>> : public std::true_type
 { using containedType = T0; };
struct Test
 {
   template <typename C, typename T = typename isCnt<C>::containedType>
   void SetData (C const & data)
    {
      if ( std::is_same<T, int>::value )
         std::cout << "- int case" << std::endl;
      else if ( std::is_same<T, float>::value )
         std::cout << "- float case" << std::endl;
    }
 };
int main ()
 {
   Test test;
   std::vector<int> vector{ 1,2,3 };
   std::array<float, 3> arr{ { 1.0f, 2.0f, 3.0f } };
   test.SetData(vector); // print "int case"
   test.SetData(arr);    // print "float case"
   //test.SetData(0);    // compilation error
 }