功能模板特化生成链接错误 [英] function template specialization generating link error

查看:117
本文介绍了功能模板特化生成链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前曾问过这个问题,该问题涉及将auto与可变参数模板一起使用,该模板生成元组和正确的迭代方法在他们之上.用户 metalfox 为我提供了这个解决方案.

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.

计算小时

#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?

推荐答案

函数模板专门化(例如您的示例中的Print<char>)是常规函数,而不是模板.必须只定义一次,否则必须用inline关键字定义.

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.

这篇关于功能模板特化生成链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆