隐藏功能模板,声明专业化

jus*_*ody 2 c++ templates declaration template-specialization

这是C++模板的后续内容:防止基本模板的实例化

我使用模板来实现函数重载而不会出现隐式类型转换:声明函数模板,定义所需的特化(重载).一切都很好,除了错误的代码在链接阶段之前不会产生错误:

lib.hpp:

template<class T> T f(T v);
Run Code Online (Sandbox Code Playgroud)

lib.cpp:

#include "lib.hpp"

template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
Run Code Online (Sandbox Code Playgroud)

main.cpp中:

#include <iostream>
#include "lib.hpp"

int main()
{
    std::cout
        << f(123L) << ", "
        << f(true) << ", "
        << f(234) << "\n"
    ;
}
Run Code Online (Sandbox Code Playgroud)

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)'
Run Code Online (Sandbox Code Playgroud)

我想在编译main.cpp时失败.我可以以某种方式声明实际实现的专业化吗?

我有什么选择?目标是C++ 03,我主要对gcc-4.x和VC9感兴趣.

Unc*_*ens 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);
}
Run Code Online (Sandbox Code Playgroud)

而且只是为了获得一般信息,C++ 0x有一个更优雅的方式来处理它:

template <class T> T f(T) = delete;

template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
Run Code Online (Sandbox Code Playgroud)

  • @Emile:空类型的大小为1. (2认同)