C++ C++;STL类型特征问题
我正在看最新的,注意到了一些有趣的事情 Stephan在介绍type_特质时,使用了以下(如他所说,人为的)例子:C++ C++;STL类型特征问题,c++,templates,stl,typetraits,C++,Templates,Stl,Typetraits,我正在看最新的,注意到了一些有趣的事情 Stephan在介绍type_特质时,使用了以下(如他所说,人为的)例子: 模板void foo(T T,true\u类型) { std::cout对于这样一个小的、人为的示例,第一种方法没有多大优势。当您遇到更复杂的情况时,优势就来了。这本质上类似于在面向对象编程中使用基于继承的多态性或if/switch语句。更复杂的解决方案允许您更大的灵活性;y您可以轻松地添加类型,而无需修改现有代码 如果您知道所有需要的类型(例如,您使用的是布尔型),那么更简单的解
模板
void foo(T T,true\u类型)
{
std::cout对于这样一个小的、人为的示例,第一种方法没有多大优势。当您遇到更复杂的情况时,优势就来了。这本质上类似于在面向对象编程中使用基于继承的多态性或if/switch语句。更复杂的解决方案允许您更大的灵活性;y您可以轻松地添加类型,而无需修改现有代码
如果您知道所有需要的类型(例如,您使用的是布尔型),那么更简单的解决方案可能会更好。但是如果您没有固定的需求(需求何时固定?),从长远来看,更复杂但更灵活的解决方案可能会更容易。基本上第一个选项使用编译时类型的“完整性”知识,第二个选项-将此知识移动到运行时
这意味着我们可以使用不可编译的整数类型代码。使用第一种方法,您可以使用if/else
或开关来实现静态分派,而不使用if/else
template <typename T>
void Dispatch(T t)
{
//Call foo(T, true_type) or foo(T, false_type)
//depending upon the *type* of second parameter.
foo(t, typename is_integral<T>::type());
}
但是如果您想实现Dispatch()
函数而不使用if/else
,同时又想使用std::is_integral::value
,那么您必须重新编写foo()
函数,如下所示
template <bool b>
void foo(T t)
{
std::cout << t << " is integral";
}
template <>
void foo<false>(T t)
{
std::cout << t << " is not integral";
}
下面的示例应该说明这一区别。让我们添加struct X:
struct X
{
X(int)
{
}
};
并修改一个foo,如下所示:
template <typename T> void foo(T t, true_type)
{
std::cout << t << " is integral";
X x(t);
}
template <typename T> void foo(T t, false_type)
{
std::cout << t << " is not integral";
}
模板无效foo(T T,真类型)
{
std::cout+1这是最重要的一点。这允许调用bar
工作,即使foo
s不支持这两种类型。回答很好!这完美地解释了它。谢谢。在C++17中,我们有if constepr
。
template <bool b>
void foo(T t)
{
std::cout << t << " is integral";
}
template <>
void foo<false>(T t)
{
std::cout << t << " is not integral";
}
template <typename T>
void Dispatch(T t)
{
//using std::is_integral<T>::value!
const bool selector = (bool) std::is_integral<T>::value;
foo<selector>(t);
}
struct X
{
X(int)
{
}
};
template <typename T> void foo(T t, true_type)
{
std::cout << t << " is integral";
X x(t);
}
template <typename T> void foo(T t, false_type)
{
std::cout << t << " is not integral";
}
template <typename T> void bar(T t)
{
foo(t, typename is_integral<T>::type());
}
template <typename T> void foo(T t)
{
if(std::is_integral<T>::value)
{
std::cout << "integral";
X x(t);
}
else
std::cout << "not integral";
}