在编译时检测typedef(模板元编程)

LiK*_*Kao 12 c++ sfinae type-traits template-meta-programming c++11

我目前正在做一些模板元编程.在我的情况下,我可以处理任何"可迭代"类型,即typedef foo const_iterator以相同方式存在的任何类型.我试图使用新的C++ 11模板元编程,但是我找不到一种方法来检测是否缺少某种类型.

因为我还需要根据其他特性打开/关闭其他模板专精,我目前正在使用带有两个参数的模板,第二个是通过生成的std::enable_if.这是我目前正在做的事情:

template <typename T, typename Enable = void>
struct Foo{}; // default case is invalid

template <typename T>
struct Foo< T, typename std::enable_if<std::is_fundamental<T>::value>::type>{ 
   void do_stuff(){ ... }
};

template<typename T>
struct exists{
   static const bool value = true;
};

template<typename T>
struct Foo<T, typename std::enable_if<exists< typename T::const_iterator >::value >::type> {
    void do_stuff(){ ... }
};
Run Code Online (Sandbox Code Playgroud)

没有exists帮助模板,我无法做到这样的事情.比如简单地做

template<typename T>
struct Foo<T, typename T::const_iterator> {
    void do_stuff(){ ... }
};
Run Code Online (Sandbox Code Playgroud)

不起作用,因为在应该使用此专门化的情况下,实例化了无效的默认情况.

但是我exists在新的C++ 11标准中找不到这个,据我所知,这个标准就是从boost::type_traits这个东西中取出来的.但是在主页boost::type_traits不显示任何东西,可以用来代替任何引用.

这个功能是否缺失,还是我忽略了其他一些明显的方法来实现所需的行为?

iam*_*ind 14

如果您只是想要一个给定的类型包含,const_iterator那么以下是您的代码的简化版本:

template<typename T>
struct void_ { typedef void type; };

template<typename T, typename = void>
struct Foo {};

template<typename T>
struct Foo <T, typename void_<typename T::const_iterator>::type> {
      void do_stuff(){ ... }
};
Run Code Online (Sandbox Code Playgroud)

有关技术如何工作的一些解释,请参阅此答案.

  • 您应该发布一个关于这个工作原理的链接.:)此外,你似乎对这一个感兴趣,看到你已经多次提出它了. (3认同)

R. *_*des 7

您可以创建一个has_const_iterator提供布尔值的特征,并在特化中使用它.

这样的事情可能会这样:

template <typename T>
struct has_const_iterator {
private:
    template <typename T1>
    static typename T1::const_iterator test(int);
    template <typename>
    static void test(...);
public:
    enum { value = !std::is_void<decltype(test<T>(0))>::value };
};
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样专注:

template <typename T,
          bool IsFundamental = std::is_fundamental<T>::value,
          bool HasConstIterator = has_const_iterator<T>::value>
struct Foo; // default case is invalid, so no definition!

template <typename T>
struct Foo< T, true, false>{ 
   void do_stuff(){// bla }
};

template<typename T>
struct Foo<T, false, true> {
    void do_stuff(){//bla}
};
Run Code Online (Sandbox Code Playgroud)

  • @nknight:原因:明确地调用`test`. (2认同)