【问题标题】:C++ boost template parameter traitsC++ 提升模板参数特征
【发布时间】:2010-07-02 19:32:11
【问题描述】:

我相信我在 boost 中看到了恢复模板模板参数的宏,例如:

template<class>
struct parameters;

#define parameters(T) template<class A> \
          struct parameters<T<A> > { typedef A type1; };

有没有这样的,还是我错了?

谢谢

【问题讨论】:

标签: c++ templates boost traits


【解决方案1】:

C++0x 中的delctype 支持使得实现起来相当简单:

template<template <typename> class Parent, typename Param1>
Param1 get_type(Parent<Param1> const &input) { return Param1(); }

SomeTpl<int> some_obj;
delctype(get_type(some_obj)) x;

(尽管您需要为具有 2、3、4 等参数的模板单独定义 get_type。)

不幸的是,我认为没有 decltype 就没有办法做到这一点,因为这样做需要函数模板提供的自动类型推导(这对类模板不可用),所以没有办法让这样的 typedef。

我不知道 boost 是否已经有类似的东西,但如果他们这样做,它仍然需要你的编译器支持decltype,但由于 decltype 是如此新,所以 boost 中没有很多东西还在使用它(尽管有一些)。

【讨论】:

    【解决方案2】:

    我已经学会相信 Johannes 的陈述,所以我有点困惑,因为这似乎用 VC10 为我编译 Ok 并打印出预期的 int

    #include <iostream>
    #include <typeinfo>
    
    template< class T >
    class steal_it;
    
    template< typename U, template<typename> class C >
    struct steal_it< C<U> > { 
        typedef U result_t;
    };
    
    template< typename T >
    class foo {};
    
    template< typename T >
    void test_it(T)
    {
        typename steal_it<T>::result_t bar = 42;
        std::cout << typeid(bar).name() << '\n';
    }
    
    int main(){
    
        test_it( foo<int>() );
    
        return 0;
    }
    

    当然,由于我没有检查任何其他编译器,这可能只是 VC 又在愚弄我......

    【讨论】:

    • 感谢您的信任 :) 我想知道是什么让您认为我会说它行不通。这也是一种特殊情况,因为您必须假设模板有一个类型参数。这种情况下也可以直接使用函数参数进行推演template&lt;template&lt;typename&gt; class C, typename U&gt; void test_it(C&lt;U&gt;) { U bar = 42; /* ... */ }。在我的另一个答案中,我指的是完全任意的模板参数列表,这不再可能了:) 您甚至可以在不评估表达式 foo&lt;int&gt;() 的情况下使用条件运算符技巧来解决这个问题。
    • @Johannes:但是是什么阻止了您将 steal_it 专门用于 1-50 个模板参数,从而获得适用于所有实际方法的通用解决方案?
    • @sbi 它不能工作,因为您需要所有参数都是类型。例如,您不能将 boost::array 传递给这样的模板。
    • @Johannes:但是非类型参数在上下文中不起作用,无论如何类型都是有用的。为了推断参数,您必须事先知道它们是类型还是其他东西。如果你知道一个参数是一个大小,你也可以用同样的方式推断出来。
    • @sbi 不,我的意思是如果你想获得一个类型参数,那么你仍然必须关心其他参数。所以对于boost::array,即使你只对类型感兴趣,那么你仍然需要推导出大小。即使您只有一个充满“大小”的参数列表,这也是不够的,因为您必须知道大小的精确类型......这是不可能解决的——实际上需要无限重载。此外,您的函数可以很好地重载,但不会给调用者返回类型。对于不能重载的,你必须使用类模板。
    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 2011-05-05
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多