隐藏功能模板,声明专业化 [英] hide function template, declare specializations

查看:132
本文介绍了隐藏功能模板,声明专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是 http://stackoverflow.com/questions/的后续追踪2050900 / c-templates-prevent-instantiation-of-base-template



我使用模板实现函数重载而没有隐式类型转换: em>声明功能模板,定义所需的特殊化(重载)。一切都很好,除非错误的代码不产生错误,直到链接阶段:



lib.hpp:

  template< class T> T f(T v); 

lib.cpp:

  #includelib.hpp

template<> long f(long v){return -v; }
template<> bool f(bool v){return!v; }

main.cpp:

  #include< iostream> 
#includelib.hpp

int main()
{
std :: cout
< f(123L) ,
<< f(true)<< ,
<< f(234) \\\

;
}

gcc输出:

  c ++ -O2 -pipe -c main.cpp 
c ++ -O2 -pipe -c lib.cpp
c + main.o lib.o -o main
main.o(.text + 0x94):在函数main中:
:未定义引用`int get< int>(int)'
pre>

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



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

解决方案

即使不将其放在单独的文件中也会产生链接器错误。



但是,为了产生其他实例化的编译器错误,请实现该函数并使用编译时断言,例如

  #include< boost / static_assert.hpp> 

template< class T> T f(T)
{
//断言一些类型相关的always-false条件,
//因此除非此函数被实例化,否则不会被触发
BOOST_STATIC_ASSERT(sizeof(T)== 0&&Only long or bool available);
}

模板<> long f(long v){return -v; }
template<> bool f(bool v){return!v; }

int main()
{
// f(100);
f(100L);
f(false);
}

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

 模板< class T> T f(T)= delete; 

模板<> long f(long v){return -v; }
template<> bool f(bool v){return!v; }


This is a followup to http://stackoverflow.com/questions/2050900/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.

解决方案

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

#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);
}

And just for general information, C++0x has a much more elegant way to deal with it:

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

template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }

这篇关于隐藏功能模板,声明专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆