C++类型特征以在 T1 和 T2 之间进行选择
C++ type traits to select between T1 and T2
我希望模板根据某些条件从两种类型中进行选择。 例如
struct Base {};
template <typename T1, typename T2>
struct test
{
// e.g. here it should select T1/T2 that is_base_of<Base>
typename select_base<T1, T2>::type m_ValueOfBaseType;
};
当然,将条件传递给select_base(使其成为通用)会很有用,但硬编码解决方案也更容易和好。
这是我尝试过的示例解决方案,但它始终选择 T1:http://ideone.com/EnVT8
问题是如何实现select_base模板。
使用 std::conditional
而不是@Matthieu在他的答案中实现if_
类模板,那么您的解决方案将简化为:
template <typename T, typename U>
struct select_base
{
typedef typename std::conditional<std::is_base_of<T, Base>::value, T, U>::type base_type;
};
或者简单地说:
template <typename T, typename U>
struct select_base : std::conditional<std::is_base_of<T, Base>::value, T, U> {};
看起来更好。
这两种解决方案之间的区别在于,在第一个解决方案中,您为嵌套类型指定了一个程序员友好的名称,正如我base_type
的那样,而在第二个解决方案中,嵌套类型只是type
看起来对程序员不友好。
请注意,在上述两种解决方案中,您必须将嵌套类型用作select_base<T,U>::base_type
(在第一个解决方案中)或select_base<T,U>::type
(在第二个解决方案中 - 因此,如果您使用typename
就像您在问题本身中编写的那样。
但是,如果改用模板别名,则定义为:
template<typename T, typename U>
using base_type = typename std::conditional<std::is_base_of<T, Base>::value, T, U>::type;
然后,您可以使用没有任何嵌套类型的base_type<T,U>
,并typename
为:
template <typename T1, typename T2>
struct test
{
//typename select_base<T1, T2>::type m_ValueOfBaseType; //ugly!
base_type<T1, T2> m_ValueOfBaseType; //better
};
希望有帮助。
C++14(及以后):
template <typename T, typename U>
struct select_base:
std::conditional_t<std::is_base_of<T, Base>::value, T, U> {};
同样,您可以改用这个:
template<typename T, typename U>
using select_base = std::conditional_t<std::is_base_of_v<T,Base>, T, U>;
使用这两种方法时,可以观察到它们之间的差异。例如,在第一种情况下,如果您必须使用::type
而在第二种情况下,则不使用。如果任何依赖类型涉及第一种方法的使用,您也必须使用 typename
来协助编译器。第二种方法没有所有这些噪音,因此优于本答案中的其他方法。
另外,请注意,您也可以在 C++11 中编写类似的类型别名。
C++11:
template <typename T, typename U>
struct select_base:
std::conditional<std::is_base_of<T, Base>::value, T, U>::type {};
// ^ ^~~~~~
C++98:
条件很简单:
template <typename bool, typename T, typename U>
struct conditional { typedef T type; };
template <typename T, typename U>
struct conditional<false, T, U> { typedef U type; };
is_base_of
稍微复杂一些,Boost 中有一个实现,我不会在这里重现。
之后,请参阅C++11。
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 线程之间的布尔停止信号
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- C++类型特征以在 T1 和 T2 之间进行选择