函数.h:
#pragma once
#include <iostream>
template<class T> void TemplatedFunction(T* p) {}
template<> void TemplatedFunction<float>(float* p) {}
template<> void TemplatedFunction<char>(char* p) {}
函数.cpp:
#include "Functions.h"
void Test()
{
TemplatedFunction<float>(NULL);
TemplatedFunction<char>(NULL);
}
主要.cpp:
#include "Functions.h"
void Test();
int main()
{
Test();
return 0;
}
构建错误:
main.obj : error LNK2005: "void __cdecl TemplatedFunction<float>(float *)" (??$TemplatedFunction@M@@YAXPAM@Z) already defined in Functions.obj
main.obj : error LNK2005: "void __cdecl TemplatedFunction<char>(char *)" (??$TemplatedFunction@D@@YAXPAD@Z) already defined in Functions.obj
我知道有两种方法可以解决这个问题:
不要将 Functions.h 包含到多个 .cpp 文件中 - 如果 h 文件包含许多 .cpp 文件所需的一些附加定义,则不能应用于复杂的项目。
将所有模板化函数声明为static。但这意味着专用函数出现在所有包含 Functions.h 的 .cpp 文件中,即使它们没有被使用,这可能会导致代码重复。
所以,我看到专门的模板函数表现得像非模板函数。如果没有 static 声明,是否还有其他解决方案可以防止链接器错误?如果函数被声明为 static,现代 C++ 编译器是否会将它们从优化构建中移除(如果它们未被使用)?
编辑。
阅读前两个答案后:我不在这里问如何防止此类链接器错误。假设我无法将特化移动到 .cpp 文件并将其保留在带有 static 或 inline 的 .h 文件中,这是否会导致优化构建中的代码重复和膨胀,当这些功能被添加到包含 .h 文件的每个 .cpp 文件中,即使它们未被使用?
最佳答案
So, I see that specialized templated function behaves like non-templated function.
正确。
Is there any other solution to prevent linker error without
staticdeclaration?
是的,就像任何普通的非模板函数一样:
Either 将函数特化定义为inline
或在 header 中声明(但不定义)特化:
template<> void TemplatedFunction<float>(float* p);
template<> void TemplatedFunction<char>(char* p);
并在 Functions.cpp 中定义它们
template<> void TemplatedFunction<float>(float* p) {}
template<> void TemplatedFunction<char>(char* p) {}
这些是比使用 static 更好的选择,因为将函数设为静态会有其他副作用,例如在每个翻译单元中为函数提供不同的地址,并使每个翻译单元中的局部静态变量不同.这是语义上的变化,而不仅仅是链接器错误的解决方案。
If functions are declared
static, does modern C++ compiler remove them from optimized build, if they are not used?
是的。但是在任何使用它们的文件中,您都会得到重复的代码,从而使可执行文件比只有一个函数定义时更大。
Assuming that I cannot move specialization to .cpp file and leave it in .h file with
static...
我看不出有什么必要这样做的充分理由,但无论如何......
... or
inline, does this cause code duplication and bloating in optimized build, when these functions are added to every .cpp file where .h file is included, even if they are not used?
不会,如果给定文件中没有使用它们,它们将不会影响从该文件编译的对象的大小。
您的问题具有误导性,因为它似乎与模板有关(标题非常清楚地说明了模板!)但是未使用的内联/静态函数是否会导致代码膨胀与函数是否为模板无关。
如果您的问题只是“未使用的内联函数和静态函数会影响对象大小吗?”对于普通函数和函数模板,答案是否定的。
关于c++ - 函数模板的显式特化导致链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25529893/
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe