给定层次结构:
struct base {};
struct a : public base {};
struct b : public base {};
我想用这个函数填充vector<base*> vecBase
和vector<a*> aVec
:
template <typename T>
void foo(T* bar) {
if (is_base_of_v<decltype(baseVec)::value_type, T>) baseVec.push_back(static_cast<decltype(baseVec)::value_type>(bar));
if (is_base_of_v<decltype(aVec)::value_type, T>) baseVec.push_back(static_cast<decltype(aVec)::value_type>(bar));
}
这里的问题是,即使static_cast
永远不会被执行,除非它是合法的;像这样的调用无法编译:
int myInt;
b myB;
foo(&myInt);
foo(&myB);
我知道我可以专攻foo
。这就是我在这里必须做的吗?或者有没有一种方法可以让编译器知道,违规的static_cast
永远不会发生?
-
static if
就是您想要的。最初由N3329于2012年1月10日提出。 -
2013年3月16日,Bjarne Stroustrup、Gabriel Dos Reis和Andrew Sutton提出了N3613,其中陈述了
static if
:
这个提议弊大于利。解决这些问题的语言功能决不能对语言和我们围绕它构建工具的能力产生负面影响。我们得出的结论是,
static if
的未来开发应该放弃,而应该采用"概念精简"方法等替代方法。
-
2013年9月23日的C++芝加哥会议上,概念研究小组表示,在不久的将来,他们不会将
static if
纳入其范围。 -
芝加哥会议确实产生了Ville Voutilainen对
static if
的简化:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html -
2015年5月4日的C++Lexena会议确实讨论了简化问题,并鼓励原作者回到2015年10月19日的C++Kona会议
-
在C++科纳会议上,Herb Sutter亲自介绍了
static if
。他回忆道,
房间里的反馈,甚至是Bjarne,都可能对它感兴趣:这可能是将Concepts/Concepts Lite版本导入C++17的唯一方法。我们没有其他方法可以将Concepts或类似的东西纳入本标准的主要修订版中。所以这还为时过早,但它已经被呈现出来了。有一些兴趣。我们现在需要跟进,这些事情确实需要时间和几个周期,但它正在被提出。
但现在你必须专门化你的模板:
template <typename T>
enable_if_t<negation_v<is_base_of<base, T>>, void> push(T*) {}
void push(base* i) {
baseVec.push_back(static_cast<decltype(baseVec)::value_type>(i));
}
void push(a* i) {
baseVec.push_back(static_cast<decltype(baseVec)::value_type>(i));
aVec.push_back(static_cast<decltype(aVec)::value_type>(i));
}