隐藏函数模板,声明专业化
C++ 模板:防止基本模板实例化的后续内容
这是 使用模板实现函数重载,而无需混乱的隐式类型转换:声明函数模板,定义所需的专业化(重载)。一切都很好,除了错误的代码在链接阶段之前不会产生错误:
lib.hpp:
template<class T> T f(T v);
lib.cpp:
#include "lib.hpp"
template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
main.cpp:
#include <iostream>
#include "lib.hpp"
int main()
{
std::cout
<< f(123L) << ", "
<< f(true) << ", "
<< f(234) << "\n"
;
}
gcc输出:
c++ -O2 -pipe -c main.cpp
c++ -O2 -pipe -c lib.cpp
c++ main.o lib.o -o main
main.o(.text+0x94): In function `main':
: undefined reference to `int get<int>(int)'
我希望它在编译main.cpp期间失败。我可以以某种方式声明仅实际实现的专业化吗?
我有什么选择?目标是C++03,我主要对gcc-4.x和VC9感兴趣。
This is a followup to C++ templates: prevent instantiation of base template
I use templates to achieve function overloading without the mess of implicit type conversions: declare the function template, define desired specializations (overloads). all is well except wrong code does not produce errors until the link phase:
lib.hpp:
template<class T> T f(T v);
lib.cpp:
#include "lib.hpp"
template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
main.cpp:
#include <iostream>
#include "lib.hpp"
int main()
{
std::cout
<< f(123L) << ", "
<< f(true) << ", "
<< f(234) << "\n"
;
}
gcc output:
c++ -O2 -pipe -c main.cpp
c++ -O2 -pipe -c lib.cpp
c++ main.o lib.o -o main
main.o(.text+0x94): In function `main':
: undefined reference to `int get<int>(int)'
I'd like to have it fail during compilation of main.cpp. Can I somehow declare only specializations actually implemented?
What are my options? The target is C++03, and I'm mainly interested in gcc-4.x and VC9.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
即使您不将其放入单独的文件中,它似乎也会产生链接器错误。
然而,要为其他实例化产生编译器错误,请实现该函数并使用编译时断言,例如,
仅出于一般信息,C++0x 有一种更优雅的方法来处理它:
It seems to produce a linker error even if you don't put it in the separate file.
However, to produce a compiler error for other instantiations, implement the function and use a compile-time assertion, e.g
And just for general information, C++0x has a much more elegant way to deal with it:
最好的方法是使用一些无效(非非法)的 C++ 代码来实现该基本模板。例如,
templateT f(T v) { return v.Default_Implementation_Not_Available; }
这个错误会在编译时出现;并且仅当您实例化“long”和“long”以外的任何版本时才会生成它。 '布尔'。如果您不实例化“int”版本,编译将正常进行。
The best way is to implement that basic template with something invalid (not illegal) C++ code. For example,
template<class T> T f(T v) { return v.Default_Implementation_Not_Available; }
This error will be compile time; and it's generated only when you instantiate any version other than 'long' & 'bool'. If you don't instantiate 'int' version, compilation will go fine.
我不相信你可以做你想做的事。有关详细信息,请参阅以下常见问题解答:
如何避免链接器错误我的模板函数?
如何避免链接器错误与我的模板类?
I don't believe it's possible to do what you want. See these FAQs for more info:
How can I avoid linker errors with my template functions?
How can I avoid linker errors with my template classes?
编译 main.cpp 时,编译器无法知道其他编译单元中可能存在哪些模板特化 - 因此无法在编译时标记此错误,您必须等到链接时。
When compiling main.cpp, there's no way for the compiler to know which template specializations may exist in some other compilation unit -- so there's no way to flag this error at compile time, you have to wait until link time.