6

次のようなテンプレートがあります。

template <class A, class B>
void func(A* a, B* b){
  ...
}

場合によっては、パラメーターB* bが必要ないことがあるため、nullptr を使用しようとします。

MyA a;
func(&a, nullptr);

nullptrどういうわけか型ではないため、コンパイラはそれを好みません。

どうすればその状況に対処できますか?唯一のアイデアは、その場合にダミータイプを使用することです。

4

4 に答える 4

13

問題は、それnullptrが実際にはポインタではなく、型のオブジェクトであることですnullptr_tA*したがって、またはのいずれとも一致しませんB*。1 つのオプションは、具体的に処理するオーバーロードを提供することnullptr_tです。

template<class A>
void func(A* a, nullptr_t)
{
    func(a, (int*)nullptr);
}

最初の引数が であることも許可したい場合は、nullptrさらに 2 つのオーバーロードを指定できます。1 つは最初の引数のみを処理し、もう 1 つは両方を処理します。

template<class B>
void func(nullptr_t, B* b)
{
    func((int*)nullptr, b);
}

void func(nullptr_t, nullptr_t)
{
    func((int*)nullptr, (int*)nullptr);
}

それ以上の引数の場合、必要なオーバーロードの数は引数の数の指数関数であるため、このアプローチはコード生成なしでは実行できなくなります。その場合、jrok のアプローチをお勧めします。

于 2015-06-07T18:49:34.587 に答える
3

Benjamin Lindleyによって提案されたオーバーロードに加えて、別のオプションは、型AおよびBがポインターまたは のいずれかである場合に関数を条件付きで有効にすることですstd::nullptr_t

#include <type_traits>

template<typename T>
struct is_pointer : std::integral_constant<bool,
                        std::is_pointer<T>::value ||
                        std::is_same<T, std::nullptr_t>::value    
                    >
{};

template <class A, class B>
typename std::enable_if<
   is_pointer<A>::value && is_pointer<B>::value
>::type
func(A a, B b) { }

ただし、最も単純なものが最適な場合もあるため、2 番目のオーバーロードでtemplate<class A> func(A*);問題が解決する場合があります。

于 2015-06-07T18:51:40.293 に答える
0

その関数を呼び出す場合は、他の方法の代わりに次の方法を実行できます。

    func<a, b>(var_a, nullptr);

これを行うことで、テンプレートを関数に渡すだけで、独自の型を持つことができます

于 2015-06-07T18:58:38.313 に答える