I am playing around with a generic template template function to output containers to the console.
To do this, I wish to provide a defaulted separator. It works defaulting a template argument to const char (but then I need to do a silly string construction) or defaulting the const char * function argument (I know this is a perfectly good solution and might be the preferred).
What I want to find out is if there is a way to default the template argument to a specific const char* value? Because the template arguments are meant to declare types not derivatives like (*, &, etc. - yet const works?) I am not sure it is possible but a defaulted template argument and more efficient than the first implementation underneath is what I am looking for.
#include <cstdlib>
#include <iostream>
#include <thread>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
// This Works
template <template <typename , typename > class Container, class Element, class Allocator, const char sep= ','>
void displayContents(const Container<Element, Allocator>& inputContainer)
{
string seperator(1, sep);
copy(inputContainer.cbegin(), inputContainer.cend(), ostream_iterator<Element>(cout, seperator.c_str())); // not all that efficient...
cout << endl;
};
// This works fine
template <template <typename, typename > class Container, class Element, class Allocator>
void displayContentsWithDefaultArgs(const Container<Element, Allocator>& inputContainer, const char* sep = ",")
{
copy(inputContainer.cbegin(), inputContainer.cend(), ostream_iterator<Element>(cout, sep));
cout << endl;
};
// how can we get this to work (more effectively than displayContents above?)
template <template <typename, typename > class Container, class Element, class Allocator, const char* sep = ",">
void displayContentsWithDefaultTemplateArgs(const Container<Element, Allocator>& inputContainer)
{
copy(inputContainer.cbegin(), inputContainer.cend(), ostream_iterator<Element>(cout, sep));
cout << endl;
};
int main(int argc, char** argv) {
vector<int> v = { 1 ,2 ,3, 4 };
vector<int> v1;
copy(v.cbegin(), v.cend(), back_inserter(v1));
displayContents(v1);
displayContentsWithDefaultArgs(v1);
displayContentsWithDefaultTemplateArgs(v1);
return 0;
}
It seems to me you want to combine two separate things in one: default type and default variable value of that type. But that's impossible and it seems pretty reasonable to me.
Slightly flexible approach will do what you asked for:
template <template <typename, typename > class Container, class Element, class Allocator, class Sep = const char*>
void displayContentsWithDefaultTemplateArgs(const Container<Element, Allocator>& inputContainer, Sep sep = ",")
{
copy(inputContainer.cbegin(), inputContainer.cend(), ostream_iterator<Element>(cout, sep));
cout << endl;
};