2

これは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に興味があります。

4

4 に答える 4

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; }
于 2010-01-28T15:48:54.617 に答える
1

最善の方法は、その基本的なテンプレートを無効な (違法ではない) C++ コードで実装することです。例えば、

template<class T> T f(T v) { return v.Default_Implementation_Not_Available; }

このエラーはコンパイル時に発生します。「long」と「bool」以外のバージョンをインスタンス化した場合にのみ生成されます。「int」バージョンをインスタンス化しない場合、コンパイルはうまくいきます。

于 2011-01-23T11:37:17.557 に答える
0

あなたのやりたいことができるとは思えません。詳細については、次の FAQ を参照してください。

テンプレート関数でリンカー エラーを回避するにはどうすればよいですか?

テンプレート クラスでリンカー エラーを回避するにはどうすればよいですか?

于 2010-01-28T15:31:06.390 に答える
0

main.cpp をコンパイルするとき、他のコンパイル ユニットにどのテンプレートの特殊化が存在する可能性があるかをコンパイラが知る方法はありません。したがって、コンパイル時にこのエラーにフラグを立てる方法はありません。リンク時まで待たなければなりません。

于 2010-01-28T15:31:45.530 に答える