在模板参数中查找类型名称的类型名称
find typename of typename in template parameter
我希望当foo从base获取任何派生内容时编译以下代码,否则会出现编译错误。我已经编写了类型特征类is_Base因为std::is_base_of
不能很好地与我的模板内容配合使用。我很接近。我用static_passoff
的东西让它工作,但我想不必使用它。那么,如果没有static_passoff
黑客,如何编写enable_if呢?这是运行版本: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;
}
鉴于您的代码确实有效,我不完全确定我是否理解您的问题。但在风格上,对于生成类型的元函数,该类型应命名为 type
。所以你应该有:
using type = decltype( test((T*)0) );
^^^^
或者,为了避免零指针投射黑客:
using type = decltype(test(std::declval<T*>()));
此外,您的test
不需要定义。只是宣言。我们实际上并没有调用它,只是检查它的返回类型。它也不必constexpr
,所以这就足够了:
template<class U>
static std::true_type test(Base<U> *);
static std::false_type test(...);
一旦你有了它,你可以给它别名:
template <typename T>
using is_Base_t = typename is_Base<T>::type;
并使用别名:
template <typename T,
typename = std::enable_if_t< is_Base_t<T>::value>>
void foo(T const&)
{
}
在盲目地进入评论中的答案后,我发现我可以在没有任何typename
关键字的情况下使用is_Base<T>::type::value
。之前尝试删除static_passoff
时,我一直在typename
.我一直和那个混在一起。无论如何,这是最终的代码,其中包含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;
}
相关文章:
- 模板元程序查找相似的连续类型名称
- 查找声明为结构类型 C++ 的数组末尾
- 按类型与字符串查找对象
- 了解元函数以在类型包中查找类型
- 如何在C++中查找类型的定义
- MFC,查找特定文件类型
- 从模板实例化/类型推断中查找错误消息的实际来源
- 查找上下文RPC_NS_HANDLE未知类型名称
- 查找树(不属于任何特定类型的简单连接树)中两个节点之间的路径
- 在数据类型类的列表中查找 elem
- 查找类型,is_constructible持有的类型
- 如何使用 std::find 从向量的第一个元素中查找字符串<字符串对<字符串、字符串> >类型?
- 使用查找表选择具有运行时索引的可变参数类型
- 如何查找一组类型对是否包含一个元素作为第二个成员
- 通过与不同类型的值进行自定义比较来查找 std::set 的元素
- 更改 std::set 以按 T 类型查找项目
- unique_ptr<int[]>、vector <int>和 int[] 的模板化类型查找
- 模板和嵌套类型查找
- 使用接口类型查找子窗口小部件
- 如何在c++中使用映射实现模板的返回类型查找