PrzgiBaklo
PrzgiBaklo

Reputation: 33

C++ function template specialization, function redefinition error

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

Answers (1)

user12002570
user12002570

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.

Method 1

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
}

working demo


Method 2

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);
    }
}

working demo

Upvotes: 0

Related Questions