-3

Consider the following declaration:

template <class T>
bool DoSomething(const T& value);

template <class D>
bool DoSomething(const std::vector<D>& value);

Is it possible to somehow unite this into single function declaration? E.g. something like that:

template <class T, class D> bool DoSomething(...);
  • 3
    What do you mean "unite this into single function declaration"? What problem are you trying to solve. No, not about "uniting this into a single function declaration", but whatever problem to which you believe the solution is to "unite this into single function declaration". – Sam Varshavchik Nov 07 '19 at 11:40
  • I was wondering is it possible to have one declaration for such function, e.g. template bool DoSomething(...); Why? Is curiosity not enough? Also while we are here, since when curiosity is punished by downvote? – Dmitrii Motorygin Nov 07 '19 at 11:42
  • 2
    You have yet to explain what this "such function" is supposed to do, or how it is supposed to work. The only thing that anyone will be able to tell you is that `template bool DoSomething();` is a valid C++ function declaration. Unles this is actually what you're asking, it is not clear exactly what you are asking, and until you make it clear nobody will be able to help you. One more time: what ***real*** problem are you trying to solve. No, not the problem about declaring such a function, but whatever problem to which you believe the solution is declaring such a function. – Sam Varshavchik Nov 07 '19 at 11:45
  • 6
    `template bool DoSomething(const T& value);` will also accept `std::vector` of any type. The question is what are you going to do with it. – Yksisarvinen Nov 07 '19 at 11:46
  • @DmitriiMotorygin I guess you receive downvotes because this seems like an XY-problem with really few information. – Lukas-T Nov 07 '19 at 12:01

4 Answers4

1

Template parameters can be types, non-types, and templates.

And I suppose you are looking at something like this

#include <iostream>
#include <list>
#include <vector>
#include <string>

template <typename T, template <typename, typename> class Cont > 
class Matrix{
public:
  explicit Matrix(std::initializer_list<T> inList): data(inList){
for (auto d: data) std::cout << d << " ";
  }
  int getSize() const{
    return data.size();
  }

private:
  Cont<T, std::allocator<T>> data;  
};

int main(){

  std::cout << std::endl;
  Matrix<int, std::vector> myIntVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
  std::cout << std::endl;
  std::cout << "myIntVec.getSize(): " << myIntVec.getSize() << std::endl;
  Matrix<std::string, std::list> myStringList{"one", "two", "three", "four"};  
  std::cout << std::endl;
  std::cout << "myStringList.getSize(): " << myStringList.getSize() << std::endl;

  std::cout << std::endl;

}

Matrix is a simple class template, that can be initialised by a std::initializer_list . A Matrix can be used with a std::vector , or a std::list to hold its values.

live Demo

Paul
  • 448
  • 1
  • 6
  • 14
1

You code

template <class T>
bool DoSomething(const T& value);

is already accepting std::vector. If you want to do something in your DoSomething method which is different if T is a vector, then you can use this approach to check if the T is a specific type. Don't forget that templates are code generators.

Soheil Armin
  • 2,725
  • 1
  • 6
  • 18
1

Well, template <class T> bool DoSomething(const T& value); can also be calles with any vector. If it works depends on what you are trying to do. Templates are just code generators. So whatever class T is, it can be used as template paramter if it has all the required members.

For example the following would work:

#include <iostream>
#include <vector>
#include <string>

class MyContainer {
public:
    size_t size() const
    {
        return 2;
    }

    int front() const
    {
        return 0;
    }

    int back() const
    {
        return 1;
    }
};

template<class T>
void foo(const T& t)
{
    if (t.size() >= 2)
    {
        std::cout << "(" << t.front() << ", " << t.back() << ")" << std::endl;
    }
}

int main()
{
    std::vector<std::string> stringVec{ "abc", "def" };

    MyContainer cont;

    foo(stringVec); // prints "(abc, def)"
    foo(cont); // prints "(0, 1)"
}

That's because both MyContainer and std::vector<std::string> have all the methods that are uses in the template. Actually this code should work with almost all STL-Containers.

Lukas-T
  • 11,133
  • 3
  • 20
  • 30
1

Short answer: Geneally you can't.

Honest answer: Yes, it can be done, depends on what you plan to do with argument. In abstract case you would need to generalize the function prototype, but still have two specializations of template using SFINAE, which makes three declarations instead of two.

Long answer: In some cases you can take advantage of if constexpr

#include <iostream>
#include <type_traits>
#include <vector>

template<typename Test, template<typename...> class Ref>
struct is_specialization : std::false_type {};

template<template<typename...> class Ref, typename... Args>
struct is_specialization<Ref<Args...>, Ref>: std::true_type {};

template <class T> bool DoSomething(const T& arg) 
{ 
    if constexpr(is_specialization<T, std::vector>::value) 
    {
        return !arg.empty();    
    } else
    {
        return bool(arg);
    }
}

int main()
{
    std::vector<int> s;
    std::cout << DoSomething(s) << std::endl;
    std::cout << DoSomething(1) << std::endl;
}
Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42