隐藏函数模板,声明专业化

发布于 2024-08-19 11:12:46 字数 1002 浏览 11 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

老街孤人 2024-08-26 11:12:46

即使您不将其放入单独的文件中,它似乎也会产生链接器错误。

然而,要为其他实例化产生编译器错误,请实现该函数并使用编译时断言,例如,

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

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; }
小忆控 2024-08-26 11:12:46

最好的方法是使用一些无效(非非法)的 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.

终止放荡 2024-08-26 11:12:46

我不相信你可以做你想做的事。有关详细信息,请参阅以下常见问题解答:

如何避免链接器错误我的模板函数?

如何避免链接器错误与我的模板类?

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?

铁轨上的流浪者 2024-08-26 11:12:46

编译 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文