像这样的常用模板专业化:
template<class T>
class C
{
void common() { ... }
void f2 = delete;
};
template<>
class C<int>
{
void common() { ... }
void f1() { ... }
};
可以用static_if
表示为:
template<class T>
class C
{
void common() { ... }
static_if(std::is_same<T, int>::value)
{
void f1( ) { ... }
}
else
{
void f2( ) = delete;
}
}
这些是直接竞争的功能吗?模板专业化可以做static_if
不能做的事情吗?似乎static_if
可以完成模板专业化所能做的所有事情,还有更多。
顺便说一句:在这种情况下,我并不喜欢static_if
,因为它可能使得在任何特定情况下您可以使用界面的哪些部分是不明显的。在某些情况下,模板特化仍然可以提供更清晰的语法。
答案 0 :(得分:10)
static if
不会为您做的一件事是使用模板专精的“主要”方式 - 在一个地方提供通用行为并让代码的用户 < strong>覆盖(= specialize)它的特定需求/数据类型/等...
答案 1 :(得分:4)
不,static_if不会弃用显式模板特化。显式模板特化是一个比static_if更强大的功能,它提供了许多静态函数不具备的功能。 static_if只是表达某些东西的一种更方便和可读的方式。
static_if不能做某些事情显式模板专业化,比如改变一个类继承的基类。
struct S {};
template<typename T>
struct T
static_if(is_same<T,int>::value) { : S } // ?
{ };
template<typename T>
struct T {};
template<>
struct T<int> : S {};
答案 2 :(得分:2)
如果是关于分支;专业化是关于匹配。有时一个比另一个好。
这是一个直接来自Alexandrescu的现代C ++设计,第11.9节“多方法”的例子:假设您有一个基于Shape
的复杂类层次结构,具有虚拟和非虚拟继承。您希望能够尽可能高效地在层次结构的成员之间进行投射。由于虚拟基础需要dynamic_cast
,我们必须考虑到这一点,但我们也希望尽可能static_cast
。通过演员政策解决方案:
template <typename To, typename From> struct ShapeCaster
{
static To & cast(From & x) { return dynamic_cast<To&>(x); }
};
template <> struct ShapeCaster<Triangle, Shape>
{
static Triangle & cast(Shape & x) { return static_cast<Triangle&>(x); }
};
template <typename To, typename From> To & shape_cast(From & x)
{
return ShapeCaster<To, From>::cast(x);
}
现在,只要您在层次结构中移动,就可以说
To & y = shape_cast<To>::cast(x);
并且您获得了最有效的演员阵容,并且可以轻松扩展该政策。
用一系列if
来写这篇文章将会更难阅读。
答案 3 :(得分:1)
static if
功能尚未成为标准。现在,假设相关问题已经解决并且使其成为标准,并且所有编译器都支持它,那么它将只是工具集中的一个工具。
我可以想象不同的情况,专业化会使代码更具可读性/可维护性,在所有这些情况下,专业化仍然是可行的方法。请注意,static if
的最大优点是您可以交错来自不同特化的代码,但这也可能是一个缺点,因为您可能最终会遇到一个巨大的blob而不是多个简单的特殊化有条件地编译/忽略的代码。
答案 4 :(得分:0)
我相信是的。 static_if
比模板特化更强大,特别是在你需要专门化一小部分类而不是整个定义的情况下。专业化更好的唯一情况 - 当您的专业实现与主要模板/其他专业化完全不同时。
答案 5 :(得分:0)
不考虑帐户首选项,仅是,如果可以使用其他模板专业化,则仅!
众所周知:std::is_same<T, int>::value
模板专门化本身!
我不确定,但我认为它的实现方式如下:
template<typename, typename>
struct is_same{
static constexpr bool value = false;;
};
template<typename T>
struct is_same<T, T>{
static constexpr bool value = true;;
};
真正的问题是,最终是否会有一种无需模板专门化的类型/类比较方法?也许只有那时,才需要模板专门化!