c – 将nullptr传递给可变参数模板指针

我目前有以下功能:

template <typename T, typename... Args> void Get(T* out, Args*... other);
template <typename T> void Get(T* out);
template <> void Get<int>(int* out);
template <> void Get<int64>(int64* out);
template <> void Get<double>(double* out);
template <> void Get<char*>(char** out);
template <> void Get<void*>(void** out);

叫做使用:

Get(&i, &t, &f);

将i作为int,将t作为char *,将f作为double.

如果我想传递空指针,这有一个例外.

Get(&i, nullptr, nullptr, &t, &f);

main.cpp: In function ‘int main()’:
main.cpp:94:39: error: no matching function for call to ‘Get(int*, std::nullptr_t, std::nullptr_t, char**, float*)’
  Get(&i, nullptr, nullptr, &txt, &f);
                                       ^
main.cpp:94:39: note: candidates are:
main.cpp:18:46: note: template<class T, class ... Args> void Get(T*, Args* ...)
 template <typename T, typename... Args> void Get(T* out, Args*... other)
                                              ^
main.cpp:18:46: note:   template argument deduction/substitution failed:
main.cpp:94:39: note:   mismatched types ‘Args*’ and ‘std::nullptr_t’
  Get(&i, nullptr, nullptr, &txt, &f);
                                       ^
main.cpp:28:28: note: template<class T> void Get(T*)
 template <typename T> void Get(T* out)
                            ^
main.cpp:28:28: note:   template argument deduction/substitution failed:
main.cpp:94:39: note:   candidate expects 1 argument, 5 provided
  Get(&i, nullptr, nullptr, &txt, &f);
                                       ^

我如何重写我的Get函数来保留旧的用法,除了它们也会接受nullptr?

最佳答案 你可以这样做:

template <typename T, typename... Args>
typename std::enable_if<std::is_same<std::nullptr_t, T>::value || std::is_pointer<T>::value>::type
Get(T out, Args... other);

template <typename T>
typename std::enable_if<std::is_same<std::nullptr_t, T>::value || std::is_pointer<T>::value>::type
Get(T out);

所以你的专业是不同的:

template <> void Get<int*>(int* out);
template <> void Get<int64*>(int64* out);
template <> void Get<double*>(double* out);
template <> void Get<char**>(char** out);
template <> void Get<void**>(void** out);

并可能:

template <> void Get<nullptr_t>(nullptr_t); // the new one

顺便说一句,你可能更喜欢重载(对于Get with one argument):Live example.

点赞