c++ - 在 C++11 中使用偏特化

标签 c++ templates c++11

我有以下代码:

template<class T, int I=44> struct test {T j = I;};

template<int J> struct test<int, J> {int j = J;};

int main()
{
  test<55> jj;

  std::cout << jj.j << std::endl;
  return(1);
}

编译器 (clang) 只提示 test<55> jj

我不明白为什么?有解决办法吗?

如果它提示那一行,为什么它不提示第二个模板定义?

提前致谢。

消息是:

enable.cpp:17:8: error: template argument for template type parameter must be a type
test<55> jj;
   ^~
enable.cpp:9:16: note: template parameter is declared here
template<class T, int I=44> struct test

最佳答案

问题是你还没有理解选择类模板特化是如何工作的。

你的专长:

template<int J> struct test<int, J> {int j = J;};

不会创建模板,您只需为其传入一个 int 模板参数。

test<55> jj; // doesn't work because there's no template<int J> struct test

相反,它所做的是创建 template<class T, int I> struct test 的特化这将在 template<class T, int I> struct test 的模板参数时使用匹配特化,即 test<int,J> .

test<int,55> jj; // uses the specialization template<int J> struct test<int, J>

这是标准中的关键引述:

In a type name that refers to a class template specialization, (e.g., A<int, int, 1>) the argument list shall match the template parameter list of the primary template. The template arguments of a specialization are deduced from the arguments of the primary template. [emphasis added]

                                                                                   — 14.5.5.1 [temp.class.spec.match] p4


您似乎试图设置 int作为 T 的默认类型同时为 I 设置一个独立的默认值.我认为您的意图是能够指定一个类型和一个值,仅指定一个类型并获取 44 作为默认值,或者仅指定一个值并获取 int 作为默认类型。

不幸的是,我不知道有什么方法可以像那样指定独立的默认值。您可以指定默认值 ( template<class T=int, int I=44> struct test ),但获取默认类型还需要接受默认值。

但是,如果您愿意使用第二个名字,那么您可以:

template <int I>
using test_int = test<int, I>;

这会创建一个模板别名,您只需指定一个值:

test_int<55> jj;

这最终将使用任何特化 test<int, I>碰巧决定是否存在显式特化或编译器生成隐式特化。

关于c++ - 在 C++11 中使用偏特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11615532/

相关文章:

c++11 - 关于在 C++11 中初始化向量

c++ - 如何在 VS2010 中将 lambda 降级为函数指针?

c++ - std::function 构造函数和 nullptr

c++ - 如何 Hook 时间功能

c++ - 重载解析和模板函数

c++ - 从 std::tuple 派生时出现混淆,无法处理 std::get

c++ - 将单元测试添加到遗留解决方案时出现链接错误

c++ - Nicolai Josuttis 在他的书中说,开放成员函数不会清除状态标志。这不是我在 VS2010 中发现的。这是微软的问题吗?

templates - Haskell - 自动使用导入模块中的变量

templates - 503型错误页面表达式引擎