Reputation: 33
So, I have an assignment for college to create templates for these functions and ive done it by the instructions.. However, the fillDefault, which I had to make a specialization for int doesnt work. I get an error "multiple definition of `void fillDefault(std::vector<int, std::allocator >&, int)'.. What can I do?
//
// Created by irept on 22/04/2023.
//
#ifndef NALOGA_7_VECTORUTIL_H
#define NALOGA_7_VECTORUTIL_H
#include <vector>
#include <iostream>
#include <random>
template<typename T>
void fillDefault(std::vector<T>& vektor, int n){
vektor.resize(n);
for(int i=0; i<n; i++){
vektor[i]=T();
}
}
template<typename T>
void print(std::vector<T>& vektor){
for(int i=0; i<vektor.size(); i++){
std::cout << vektor[i] << " ";
}
std::cout << std::endl;
}
template<typename T>
void reverse(std::vector<T>& vektor){
int j=0;
std::vector<T> reverse(vektor.size());
for(int i=vektor.size(); i>0; i--){
reverse[j]=vektor[i-1];
j++;
}
for(int i=0; i<vektor.size(); i++){
vektor[i]=reverse[i];
}
}
template<typename T>
std::vector<T> mergeVectors(std::vector<std::vector<T>>& vektorVektorjev){
std::vector<T> merged;
for(int i=0; i<vektorVektorjev.size(); i++){
merged.insert(merged.end(), vektorVektorjev[i].begin(), vektorVektorjev[i].end());
}
return merged;
}
template<>
void fillDefault(std::vector<int>& vektor, int n){
for(int i=0; i<n; i++){
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist (1, 100);
int value=dist(gen);
vektor.push_back(value);
}
}
#endif //NALOGA_7_VECTORUTIL_H
I tried moving the definition into the .cpp file like chatgpt said, but that resulted in other errors.
Upvotes: 1
Views: 112
Reputation: 1
The problem is that an explicit specialization behaves as a non templated entity so that you can either move the explcit specialization into a source file or use the keyword inline
when using it in header file. That is, there are 2 ways to solve this problem, both of which are shown below.
One way to solve this is to add the keyword inline
when specializing the function template as shown below:
header.h
//other code as before
template<>
vvvvvv---------------------------------------------------->added this inline keyword
inline void fillDefault(std::vector<int>& vektor, int n){
//other code as before
}
Second option is to move the specialization into a source file as shown below:
source.cpp
#include"header.h"
template<>
inline void fillDefault(std::vector<int>& vektor, int n){
for(int i=0; i<n; i++){
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist (1, 100);
int value=dist(gen);
vektor.push_back(value);
}
}
Upvotes: 0