这个问题在这里已经有了答案:
(Partially) specializing a non-type template parameter of dependent type
(4 个回答)
6年前关闭。
我想对结构进行专门化,其中一个使用函数指针而另一个不使用。但是,当我这样做时:
template <typename T, T*>
struct test;
template <typename T>
struct test<T, nullptr>
{
};
template <typename R, typename...ARGs, R(*fn)(ARGs...)>
struct test<R(ARGs...), fn>
{
};
我收到此错误:
error: type 'T*' of template argument 'nullptr' depends on a template parameter
struct test<T, nullptr>
这究竟是什么意思,我该如何进行这项工作?
最佳答案
linked question描述了主要问题和一些解决方案,但由于涉及相当多,我已将它们应用于您的特定问题。
版本 1
我们实际上可以使用 std::integral_constant
保存指针,因此我们可以利用这一事实来绕过对非类型参数的限制:
template <typename T, typename U>
struct test;
template <typename T>
struct test<T, std::integral_constant<T*,nullptr>>
{
void operator()() { std::cout << "nullptr" << std::endl; }
};
template <typename R, typename...ARGs, R(*fn)(ARGs...)>
struct test<R(ARGs...), std::integral_constant<R(*)(ARGs...),fn>>
{
void operator()() { std::cout << "fnptr" << std::endl; }
};
不幸的是,用法看起来很丑,但它有效:
test<int,std::integral_constant<int*,nullptr>> a;
a();
test<decltype(foo), std::integral_constant<decltype(&foo), foo>> b;
b();
版本 2
此版本使用
std::enable_if
进行检查而不是部分特化:template <typename T, T*, typename = void>
struct test;
template <typename T, T* P>
struct test<T, P, typename std::enable_if<(P==nullptr)>::type>
{
void operator()() { std::cout << "nullptr" << std::endl; }
};
template <typename T, T* P>
struct test<T, P, typename std::enable_if<std::is_function<T>::value>::type>
{
void operator()() { std::cout << "fnptr" << std::endl; }
};
这的用法可能是您最初打算的:
test2<int, nullptr> c;
c();
test2<decltype(foo), foo> d;
d();
在此版本中,您无法立即访问用作模板参数的函数指针的参数类型,但如果需要,您可以轻松编写一些其他特征来获取它们。
这是一个 Live Demo这显示两个版本都在工作。
关于c++ - 为什么我不能专门针对依赖类型使用 nullptr 模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32097620/