获得模板化模板函数声明正确

时间:2017-09-08 23:46:51

标签: c++ c++11 templates stl variadic-templates

我遇到了这样的问题,我正在尝试编译:

#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;
}

基本上我需要一个可以接受任何仲裁STL容器的函数签名(更具体地说是std::vectorstd::array),我还需要函数中可见的T类型(即{{ 1}}或int在这种情况下)。我不关心的其他类型(分配器或float大小)。

什么是正确的签名?

1 个答案:

答案 0 :(得分:0)

  

什么是正确的签名?

据我所知,无法编写一个正确的签名来拦截所有容器,只能拦截容器。

但是如果你接受写一个类型特征,说明一个类型是一个容器并提取所包含的类型(需要一个通用版本,一个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&gt;    void SetData(C const&amp; data)     {       //代码在这里     }

观察setData() T = isCnt<C>::containedType#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 } 启用(或禁用)SFINAE,仅适用于容器。

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

double weight_Fee = 0.5 * animal_Weight;