这是C++ templates: prevent instantiation of base template
的后续内容我使用模板来实现函数重载而不会出现隐式类型转换:声明函数模板,定义所需的特化(重载)。一切都很好,除了错误的代码在链接阶段之前不会产生错误:
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感兴趣。
答案 0 :(得分:5)
即使您没有将它放在单独的文件中,它似乎也会产生链接器错误。
但是,要为其他实例化生成编译器错误,请实现该函数并使用编译时断言,例如
#include <boost/static_assert.hpp>
template <class T> T f(T)
{
//assert some type-dependent "always-false" condition,
//so it won't be triggered unless this function is instantiated
BOOST_STATIC_ASSERT(sizeof(T) == 0 && "Only long or bool are available");
}
template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
int main()
{
//f(100);
f(100L);
f(false);
}
就一般信息而言,C ++ 0x有一个更优雅的方式来处理它:
template <class T> T f(T) = delete;
template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
答案 1 :(得分:1)
最好的方法是使用无效(非非法)C ++代码实现该基本模板。例如,
template<class T> T f(T v) { return v.Default_Implementation_Not_Available; }
此错误将是编译时间;并且仅当您实例化除“long”之外的任何版本时才会生成它。 'bool的'。如果你没有实例化'int'版本,编译就可以了。
答案 2 :(得分:0)
我不相信你可以做你想做的事。有关详细信息,请参阅这些常见问题解答:
答案 3 :(得分:0)
编译main.cpp时,编译器无法知道某些其他编译单元中可能存在哪些模板特征 - 因此在编译时无法标记此错误,您必须等到链接时间。< / p>