【问题标题】:How to determine if a type is derived from a template class?如何确定类型是否派生自模板类?
【发布时间】:2011-08-25 06:33:03
【问题描述】:

如何确定一个类型是否派生自模板类?特别是,我需要确定模板参数是否具有std::basic_ostream 作为基类。通常std::is_base_of 是工作的工具。但是,std::is_base_of 仅适用于完整类型而不适用于类模板。

我正在寻找这样的东西。

template< typename T >
bool is_based_in_basic_ostream( T&& t )
{
   if( std::is_base_of< std::basic_ostream< /*anything*/>, T >::value )
   {
      return true;
   }
   else
   {
      return false;
   }
}

我确定这可以做到,但我想不出怎么做。

【问题讨论】:

  • 只是想扔进去......你可以用一个返回 if 语句中条件的 return 行替换整个 if/else 分支!
  • typename T 是一个完整的类型吗?你会在你的代码中指定什么/* anything */
  • 在我的情况下,我只希望在那里看到完整的字符类型。我相信 basic_ostream 不能被实例化,除非/*anything*/ 是一个完整的类型。

标签: c++ templates metaprogramming c++11 typetraits


【解决方案1】:

我不知道有一种简洁的方法。但是你可以再次滥用重载

template< typename T, typename U >
std::true_type is_based_impl( std::basic_ostream<T, U> const volatile& );
std::false_type is_based_impl( ... );

template< typename T >
bool is_based_in_basic_ostream( T&& t ) {
  return decltype(is_based_impl(t))::value;
}

它只会检测公共继承。请注意,您可以改为检测来自ios_base 的派生,这可能对您同样有效(此测试也对输入流是肯定的,因此它的适用性有限)

std::is_base_of<std::ios_base, T>

【讨论】:

  • 检查std::ios_base 的问题在于它也会检测输入流,这可能会违反 OP 所希望的语义。
  • @ildjarn 我同意。我想我应该更清楚。感谢您明确指出。固定:)
  • 您使用const volatile&amp;,而不仅仅是const&amp;,是否有具体原因?
【解决方案2】:

你所追求的是像 Boost 的 is_instance_of 这样的东西吗?

http://www.boost.org/doc/libs/1_46_1/boost/lambda/detail/is_instance_of.hpp

这是 1 参数模板的简短版本:

#include <iostream>
#include <type_traits>

template <template <typename> class F>
struct conversion_tester
{
        template <typename T>
        conversion_tester (const F<T> &);
};

template <class From, template <typename> class To>
struct is_instance_of
{
        static const bool value = std::is_convertible<From,conversion_tester<To>>::value;
};

template <typename T>
struct foo {};

template <typename T>
struct bar {};

int main()
{
        std::cout << is_instance_of<foo<int>,foo>::value << '\n'; // This will print '1'.
        std::cout << is_instance_of<bar<int>,foo>::value << '\n'; // This will print '0'.
}

不幸的是,如果您尝试将其扩展到可变参数模板,使用当前的 GCC (4.6.0) 会产生错误消息。 This SO answer 暗示这是当前 GCC 的问题,并且可变参数模板版本应该按照标准工作。

【讨论】:

    猜你喜欢
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多