Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check at compile-time is a template type a vector

Tags:

c++

templates

I can imagine the following code:

template <typename T> class X
{
  public:
   T container;

   void foo()
   {
      if(is_vector(T))
         container.push_back(Z);
      else
         container.insert(Z);
   }
}

// somewhere else...

X<std::vector<sth>> abc;
abc.foo();

How to write it, to successfully compile? I know type traits, but when I'm defining:

template<typename T> struct is_vector : public std::false_type {};

template<typename T, typename A>
struct is_vector<std::vector<T, A>> : public std::true_type {};

It doesn't compile:

error: no matching function for call to 'std::vector<sth>::insert(Z)'

static_assert also isn't that what I'm looking for. Any advices?

Here's a short example of what I want to achieve (SSCCE): http://ideone.com/D3vBph

like image 615
mkzwm Avatar asked Feb 02 '14 15:02

mkzwm


People also ask

Is a template a vector?

vector is a template class, which can be instantiated with a type, in the format: vector<int> , vector<double> , vector<string> . The same template class can be used to handle many types, instead of repeatably writing codes for each of the type.

Are templates compile-time?

The use of templates can be thought of as compile-time polymorphism. The technique is used by a number of languages, the best-known being C++, but also Curl, D, Nim, and XL.

Are templates evaluated at compile-time?

1.1.2 Using Function Templates A template is visited twice by the compiler. On first pass it's simply checked for correct syntax. It's only actually compiled when it is used (instantiated) in code.

Are C++ templates compile-time?

3 Compile-Time Instantiation. Instantiation is the process by which a C++ compiler creates a usable function or object from a template. The C++ compiler uses compile-time instantiation, which forces instantiations to occur when the reference to the template is being compiled.


1 Answers

It is named tag dispatching :

#include <vector>
#include <set>
#include <type_traits>

template<typename T> struct is_vector : public std::false_type {};

template<typename T, typename A>
struct is_vector<std::vector<T, A>> : public std::true_type {};

template <typename T>
class X {
    T container;

    void foo( std::true_type ) {
        container.push_back(0);
    }
    void foo( std::false_type ) {
        container.insert(0);
    }
public:
    void foo() {
        foo( is_vector<T>{} );
    }
};

// somewhere else...
int main() {
    X<std::vector<int>> abc;
    abc.foo();

    X<std::set<int>> def;
    def.foo();
}
like image 191
galop1n Avatar answered Sep 23 '22 22:09

galop1n