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

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-11 05:54:38

问题


Given the hierarchy:

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

I want to fill vector<base*> vecBase and vector<a*> aVec with this function:

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

The problem here is that even though the static_cast will never be performed unless it's legal; calls like these fail to compile:

int myInt;
b myB;

foo(&myInt);
foo(&myB);

I know that I can specialize foo. Is that what I have to do here, or is there a way to tip the compiler off to the fact that the offending static_casts will never happen?


回答1:


  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 which stated of 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. The C++ Chicago Meeting on Sep-23-'13 the Concepts Study Group stated that they weren't including static if in their scope for the near future.

  2. The Chicago Meeting did spawn Ville Voutilainen's simplification of static if: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html

  3. The C++ Lexena Meeting on May-4-'15 did discuss the simplification and encouraged the original authors to come back to the C++ Kona meeting on Oct-19-'15

  4. In the C++ Kona Meeting Herb Sutter personally presented static if. He recounts that,

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.


But for now you're going to have to specialize your templates:

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


来源:https://stackoverflow.com/questions/37545078/do-i-have-to-specialize-templates-if-their-offending-code-is-in-an-iffalse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!