问题
I had previously asked this question that involved using auto with variadic templates that generates a tuple and the proper way to iterate over them. User metalfox had provided me with this solution.
I tried their solution and this is what my full code looks like including my namespace that I had omitted in the original.
calc.h
#include <algorithm>
#include <iostream>
#include <tuple>
#include <utility>
namespace math {
template<class... T>
class expression_t {
public:
std::tuple<T...> rhs;
std::size_t size = sizeof...(T);
//expression_t(const T&... args) : rhs{ args... } {}
template <class... Args>
expression_t(Args&& ...args) : rhs(std::forward<Args>(args)...) {}
std::tuple<T...> operator()() const {
return rhs;
}
};
template<typename T>
void Print(std::ostream& os, T x) {
os << x;
}
template<>
void Print<char>(std::ostream& os, char x) {
if (x == '+' || x == '-' || x == '*' || x == '/' || x == '%')
os << ' ' << x << ' ';
}
template<class... Args>
expression_t<Args...> expression(Args... args) {
expression_t<Args...> expr(args...);
return expr;
}
template<class... Args>
std::ostream& operator<<(std::ostream& os, const expression_t<Args...>& expr) {
auto Fn = [&os](auto... x) {
(Print(os, x), ...);
};
std::apply(Fn, expr.rhs);
os << '\n';
return os;
}
}
main.cpp
#include "calc.h"
using namespace math;
int main() {
double x = 0;
auto expr = expression(4, x, '^', 2, '+', 2, x);
auto t = expr();
std::cout << std::get<2>(t);
std::cout << expr;
return 0;
}
It is generating this linker error during the build process:
1>------ Build started: Project: ChemLab, Configuration: Debug x64 ------
1>main.obj : error LNK2005: "void __cdecl math::Print<char>(class std::basic_ostream<char,struct std::char_traits<char> > &,char)" (??$Print@D@math@@YAXAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@D@Z) already defined in calc.obj
1>C:\***\test.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Done building project "ChemLab.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
What is the proper way to declare-define these print functions to prevent them from being defined multiple times in a single translation unit?
回答1:
A function template specialization - like Print<char>
in your example - is a regular function, not a template. It must be defined exactly once, or else defined with inline
keyword.
来源:https://stackoverflow.com/questions/56709825/function-template-specialization-generating-link-error