c++ - 为什么我不能专门针对依赖类型使用 nullptr 模板参数?

标签 c++ templates c++11 template-meta-programming

这个问题在这里已经有了答案:





(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/

相关文章:

c++ - ODBC API 查询参数

c++ - 如何在不更改所有代码以使用 this-> 的情况下避免旧模板重库中的 'not declared' 错误?

c++ - 错误消息与命名右值引用混淆

c++ - 动态更改文本 qlabel

c++ - 在 C++ 中解析 HTTP header

c++ - 将枚举传递给另一个文件? C++

c++ - 为 C++ 设置 Direct X 时出现问题

c++ - 模板类中的双嵌套类前向声明

c++ - 参数值相等时的模板特化

c++ - 使用 c++11/最近的 g++ 版本 (4.7/4.6) 的可移植性