如果他们的违规代码在 if(false) 中,我是否必须专门化模板

Do I Have to Specialize Templates If Their Offending Code Is in an if(false)

给定层次结构:

struct base {};
struct a : public base {};
struct b : public base {};

我想用这个函数填充 vector<base*> vecBasevector<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_casts 永远不会发生?

  1. static if is what you're looking for. It was originally proposed by N3329 on Jan-10-'12.

  2. On Mar-16-'13 Bjarne Stroustrup, Gabriel Dos Reis, and Andrew Sutton put forward N3613 表示 static if:

This proposal would do much more harm than good. Language features addressing these problems must not negatively affect the language and our ability to build tools around it. We conclude that future development of static if should be abandoned, and that alternatives such as "concepts-lite" approach should be pursued instead.

  1. 2013 年 9 月 23 日的 C++ 芝加哥会议上,概念研究小组表示他们 weren't including static if in their scope for the near future.

  2. 芝加哥会议确实催生了 Ville Voutilainen 对 static if 的简化:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html

  3. 2015 年 5 月 4 日的 C++ Lexena 会议确实讨论了简化和 encouraged the original authors to come back to the C++ Kona meeting on Oct-19-'15

  4. 在 C++ Kona 会议中 Herb Sutter personally presented static if。他回忆说,

The feedback in the room, even Bjarne, was potentially interested in it from the point of view: This may be the only way to get a version of Concepts/Concepts Lite into C++17. There's no other way we'll get Concepts or anything like it into this major revision of the standard. So this is early days yet, but it has been presented. There is some interest. We now need to follow up and these things do take time and several cycles, but it is being proposed.


但是现在您必须专门化您的模板:

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));
}