不同的.cpp文件中的相同C ++模板用法是否重复代码?

问题描述

假定您在另外两个.cpp文件template_function<T>()a_uses_template.cpp)中使用相同的b_uses_template.cpp,这两个文件都隐式实例化了模板。

据我了解,这应该会导致代码重复,因为a_uses_template.cppb_uses_template.cpp是分别编译的,因此template_function<T>()被实例化两次。
但是,如果我更改代码以仅使用一种显式实例化,则生成的可执行文件将更大,而不是预期的小。

这怎么可能?

main.cpp

#include <iostream>
#include "a_uses_template.h"
#include "b_uses_template.h"

int main() {
    function_a_uses_template();
    function_b_uses_template();
}

a_uses_template.h

#ifndef A_USES_TEMPLATE_H_
#define A_USES_TEMPLATE_H_

void function_a_uses_template();

#endif /* A_USES_TEMPLATE_H_ */

a_uses_template.cpp

#include <iostream>
#include "template_function.h"
#include "a_uses_template.h"

void function_a_uses_template() {
    std::cout << "function_a_uses_template,template_function<int>(): "
            << template_function<int>() << std::endl;
}

以下是template_function.h /.cpp的两个变体,首先是with与两个隐式实例一起使用,然后是两个包含一个显式实例的文件

template_function.h(带有两个隐式实例的变体)

#ifndef TEMPLATE_FUNCTION_H_
#define TEMPLATE_FUNCTION_H_

#include <cstddef>

template<typename T> size_t template_function() {
    size_t s = sizeof(T);

    // some code that the compiler won't erase during optimization
    while (s != 1) {
        if ((s & 1) == 0) {
            s /= 2;
        } else {
            s = 3 * s + 1;
        }
    }

    return s;
}

#endif /* TEMPLATE_FUNCTION_H_ */

template_function.h(带有一个明确实例的变体)

#ifndef TEMPLATE_FUNCTION_H_
#define TEMPLATE_FUNCTION_H_

#include <cstddef>

template<typename T> size_t template_function();

#endif /* TEMPLATE_FUNCTION_H_ */

template_function.cpp(带有一个明确实例的变体)

#include "template_function.h"

template<typename T> size_t template_function() {
    size_t s = sizeof(T);

    // some code that the compiler won't erase during optimization
    while (s != 1) {
        if ((s & 1) == 0) {
            s /= 2;
        } else {
            s = 3 * s + 1;
        }
    }

    return s;
}

template size_t template_function<int>(); // one explicit instanciation

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)