【问题标题】:Extract the generic type of another generic type in C++在 C++ 中提取另一个泛型类型的泛型类型
【发布时间】:2014-04-24 12:30:09
【问题描述】:

假设我有一个类 Foo,它使用两种不同的泛型类型,一种是_Type,另一种是_Comparator_Type 已知是 std::vectorstd::liststd::string,因此它内部会有一个类型:T 将在 vectorlist 之内; char 将在 string 内。

我的另一个泛型类型_Comparator 是一个可选模板参数,用户可以通过它指定她自己的小于函数、仿函数或lambda 函数。如果没有提供参数作为第二个模板参数,它应该默认为std::less<M> 函子,其中M 类型应该是_Type 中包含的元素的类型。

我不知道如何执行此操作的语法。

我试过了:

template <typename _Type<T>, typename _Comparator = less<T> >

无济于事。

【问题讨论】:

  • 请注意,你的名字是无效的:下划线后跟大写字母的名字是为实现保留的,你不能在代码中自己使用。
  • 所有容器类型内部都有一个value_type typedef。因此,如果您确定 Type 将始终是一个容器,您可以使用 Type::value_type 来访问包含的类型。是的,std::string 是一个容器,一个非常专业的容器。
  • @KonradRudolph 我有点困惑:为哪个实现保留?另外,模板参数的名称是在家庭作业中给出的,所以我认为它们应该是有效的,否则我在这里误解了你。
  • 编译器实现。如果你的老师给了你这些名字,你应该告诉老师停下来。
  • 注明。我会向他提出这一点。

标签: c++ templates generics


【解决方案1】:

使用@Joachim Pileborg 在 cmets 中提到的方法,我能够想出以下方法,这使我能够访问_Type 的内部类型:

template <typename _Type, 
    typename _Comparator = less<typename _Type:: value_type> >
class Foo
{
    public:
        // some methods
    private:
        _Type sequence;
        _Comparator comparator;
};

现在std::less 比较正确的类型而不会抱怨。

【讨论】:

    【解决方案2】:

    如果我正确理解了您的问题,您可以尝试以下方法:

    #include <iostream>
    #include <vector>
    #include <list>
    #include <typeinfo>
    
    template <typename T>
    class holder
    {
    public:
        template <typename Type = std::vector<T>, typename Comparator = std::less<T> >
        class impl
        {
        public:
            impl() {std::cout << typeid(s).name() << std::endl; }
            Type s;
        };
    
    } ;
    
    int main()
    {
        holder<int>::impl<> holder_of_int_vectors;
        holder<int>::impl<std::list<int> > holder_of_int_lists;
        holder<int>::impl<std::list<int>, std::greater<int> > holder_of_int_lists_with_greater;
    }
    

    即,使用一个外部类来保存“基本”类型 (T),并使用一个内部类来保存容器 (Type) 和比较器。

    【讨论】:

    • Type 没有默认模板参数,例如std::vector
    • 没关系,只需删除它,在这种情况下,您还需要明确指定 holder_of_int_vectors 为:holder&lt;int&gt;::impl&lt;std::vector&lt;int&gt; &gt;
    【解决方案3】:

    正如你所说,你只想支持vectorliststring,你可以使用这个:

    template <typename T, typename Compare = std::less<typename T::value_type>>
    

    这将支持所有具有成员 typedef value_typevectorliststring 的类型。

    使用可变参数模板模板参数可以支持其他类型,但这变得更加复杂。

    【讨论】:

    • 是的,这就是我最终使用的。请参阅下面的答案。我认为它以简单取胜,因为我不需要全面的支持。
    猜你喜欢
    • 2021-12-25
    • 2014-08-02
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    相关资源
    最近更新 更多