2015-06-07 2 views
3

У меня есть шаблон, как:nullptr в качестве параметра шаблона

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

В некоторых случаях бывает, что параметр B* b не нужен, и поэтому я стараюсь использовать nullptr:

MyA a; 
func(&a, nullptr); 

компилятору это не нравится, так как nullptr как-то не тип.

Как я могу справиться с этой ситуацией? Единственная идея - просто использовать фиктивный тип для этого случая.

+3

'nullptr' имеет тип' nullptr_t'. – phantom

+1

Какое сообщение об ошибке? – martin

ответ

7

Проблема в том, что nullptr на самом деле не указатель, а объект типа nullptr_t. Поэтому он не может соответствовать A* или B*. Один из вариантов заключается в том, чтобы обеспечить перегруз для специфической обработки nullptr_t.

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

Если вы хотите, чтобы позволить первый аргумент быть nullptr, вы можете предоставить еще 2 перегрузкам. Один для обработки только первого аргумента, и один для обработки обоих.

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.

2

Кроме перегрузкой в ​​предложенной Benjamin Lindley, другой вариант conditionaly включить функцию, если типы 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) { } 

Но иногда самое простое это лучшее, так что, возможно вторая перегрузка template<class A> func(A*); выполнит эту работу.

0

, когда вы хотите вызвать эту функцию, вы можете сделать следующее вместо других способов:

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

, делая это, вы просто передать шаблон функционировать, и вы можете иметь свой собственный тип

Смежные вопросы