specializing functions on stl style container types

六眼飞鱼酱① 提交于 2019-12-22 10:54:02

问题


If i have a type T, what is a useful way to inspect it at compile time to see whether its an STL-style container (for an arbitrary value type) or not?
(Assumption: pointers, reference, etc. already stripped)

Starting code:

template<class T> // (1)
void f(T&) {} 

template<class T> // (2)
void f(std::vector<T>&) {} 

void test() 
{
    int a;
    std::vector<int> b;
    f(a);
    f(b);
}

Now this works fine, but what if i want to generalize the container (i.e. not define (3), (4), ... explicitly)?

Utilizing SFINAE and typelists would reduce the code somewhat, but is there a better way?
Or is there an idiom for specializing based on concepts?
Or could i somehow utilize SFINAE to selectively enable only the desired specializations?

As a sidenote, i can't use iterators - i am trying to specialize based on functions that receive Ts as parameters.


As per MSalters answer:

template<class T>
void f(T&, ...) {
    std::cout << "flat" << std::endl; 
}

template<class Cont>
void f(Cont& c, typename Cont::iterator begin = Cont().begin(),
                typename Cont::iterator end   = Cont().end()) {
    std::cout << "container" << std::endl; 
}

(The variable argument list is needed to make the first f the least preferred version to solve ambiguity errors)


回答1:


STLcontainers by definition have a typedef iterator, with 2 methods begin() and end() retruning them. This range is what the container contains. If there's no such range, it's not a container in the STL sense. So I'd sugegst something along the line of (not checked)

template<typename CONTAINER>
void f(CONTAINER& c,
       typename CONTAINER::iterator begin = c.begin(),
       typename CONTAINER::iterator end = c.end())
{ }



回答2:


Anything you do is almost certain to be extremely fragile. There's simply no clean dividing line between what is or is not "STL". Even if there was a clean dividing line, it would almost certainly be a really poor basis for such a decision in any case. Just for example, if I write (or use) a re-implementation of std::map that's uses an AVL tree instead of the more common R-B tree, why should it be treated differently from std::map?

In the case of hashed containers, there's a whole progression from the various implementations of hash_map, to the Boost containers, to the TR1 containers, to those that will be included in the standard library in C++ 0x. Depending on how you define "STL", there's a pretty good chance that at least one of those isn't STL and another is, but there's no one point at which it's likely to make sense to treat one differently from another.

I think you should think about the characteristics of the containers, and then try to identify the characteristics that really matter to you.




回答3:


According to www.cplusplus.com, the only functions that are common to all STL containers are:

  • A constructor
  • operator=
  • size.

At compile time, you can determine whether these operators exist on your type T.



来源:https://stackoverflow.com/questions/1904796/specializing-functions-on-stl-style-container-types

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