简体   繁体   English

在模板参数中找到typename的typename

[英]find typename of typename in template parameter

I would like the following code to compile when foo gets anything derived from base, otherwise a compile error ensues. 我想在foo获取任何从base派生的内容时编译以下代码,否则会发生编译错误。 I have written the type-trait class is_Base because the std::is_base_of does not work well with my template stuff. 我写了类型特征类is_Base,因为std::is_base_of不能很好地与我的模板配合使用。 I am close. 我近了 I got it to work using a static_passoff thing, but I would like to not have to use it. 我使用static_passoff东西使它工作,但我不想使用它。 So how can write the enable_if without the static_passoff hack? 那么,如何在没有static_passoff hack的情况下编写enable_if? Here is the running version: http://coliru.stacked-crooked.com/a/6de5171b6d3e12ff 这是运行的版本: http : //coliru.stacked-crooked.com/a/6de5171b6d3e12ff

#include <iostream>
#include <memory>

using namespace std;

template < typename D >
class Base
{
public:
    typedef D EType;
};

template<class T>
struct is_Base
{
    using base_type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;

    template<class U>
    static constexpr std::true_type test(Base<U> *) { return std::true_type(); }
    static constexpr std::false_type test(...) { return std::false_type(); }

    using value = decltype( test((T*)0) );
};

template < typename A >
using static_passoff = std::integral_constant< bool, A::value >;

template <typename T, typename = typename std::enable_if< static_passoff< typename is_Base< T >::value >::value >::type >
void foo(T const&)
{
}


class Derived : public Base<Derived> {};
class NotDerived {};


int main()
{
    Derived d;
    //NotDerived nd;

    foo(d);
    //foo(nd); // <-- Should cause compile error

    return 0;
}

I'm not entirely sure I understand your question given that your code does work. 考虑到您的代码确实有效,我不确定是否能理解您的问题。 But stylistically, for metafunctions that yield a type, that type should be named type . 但是从风格上讲,对于产生类型的元函数,该类型应命名为type So you should have: 因此,您应该具有:

using type = decltype( test((T*)0) );
      ^^^^

Or, to avoid the zero-pointer-cast-hack: 或者,为了避免零指针广播黑客:

using type = decltype(test(std::declval<T*>()));

Also, your test doesn't need a definition. 另外,您的test不需要定义。 Just the declaration. 只是宣言。 We're not actually calling it, just checking its return type. 我们实际上没有调用它,只是检查它的返回类型。 It doesn't have to be constexpr either, so this suffices: 它也不必是constexpr ,所以就足够了:

template<class U>
static std::true_type test(Base<U> *);
static std::false_type test(...);

Once you have that, you can alias it: 一旦有了它,就可以对其进行别名:

template <typename T>
using is_Base_t = typename is_Base<T>::type;

And use the alias: 并使用别名:

template <typename T, 
          typename = std::enable_if_t< is_Base_t<T>::value>>
void foo(T const&)
{
}

After stumbling blindly into the answer in the comments, I found out I can just use is_Base<T>::type::value without any typename keywords. 盲目地陷入评论的答案之后,我发现我可以只使用is_Base<T>::type::value而无需任何typename关键字。 When trying to remove the static_passoff before, I kept putting in typename . 在尝试删除static_passoff之前,我一直输入typename I have always been mixed up with that one. 我一直都和那个混在一起。 Anyway, here is the final code with a few teaks from Barry's answer: 无论如何,这是最终的代码,其中有一些来自Barry的回答:

#include <iostream>
#include <memory>

using namespace std;

template < typename D >
class Base
{
public:
    typedef D EType;
};

template<class T>
struct is_Base
{
    using base_type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;

    template<class U>
    static constexpr std::true_type test(Base<U> *) { return std::true_type(); }
    static constexpr std::false_type test(...) { return std::false_type(); }

    using type = decltype(test(std::declval<T*>()));
};

template <typename T, typename = typename std::enable_if< is_Base< T >::type::value >::type >
void foo(T const&)
{
}


class Derived : public Base<Derived> {};
class NotDerived {};


int main()
{
    Derived d;
    //NotDerived nd;

    foo(d);
    //foo(nd); // <-- Should cause compile error

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM