Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板结构内部模板结构的模板专业化失败_C++_Templates_C++11_Partial Specialization - Fatal编程技术网

C++ 模板结构内部模板结构的模板专业化失败

C++ 模板结构内部模板结构的模板专业化失败,c++,templates,c++11,partial-specialization,C++,Templates,C++11,Partial Specialization,我似乎不知道下面的例子出了什么问题 $ cat repro.cpp #include <iostream> using namespace std; template<class T> struct S1_t { template<class U> struct inner_t_x {}; using inner_t = inner_t_x<T>; }; struct Bogus{}; template<class T>

我似乎不知道下面的例子出了什么问题

$ cat repro.cpp
#include <iostream>
using namespace std;

template<class T>
struct S1_t
{
  template<class U>
  struct inner_t_x {};

  using inner_t = inner_t_x<T>;
};
struct Bogus{};

template<class T>
struct Functor1
{
  void operator()() 
  {
    cout << "Functor1 FAIL: " << __PRETTY_FUNCTION__ << endl;
  }
};
template<>
struct Functor1<typename S1_t<Bogus>::template inner_t_x<Bogus>>
{
  void operator()() 
  {
    cout << "Functor1 PASS: " << __PRETTY_FUNCTION__ << endl;
  }
};

template<class T>
struct Functor2
{
  void operator()() 
  {
    cout << "Functor2 FAIL: " << __PRETTY_FUNCTION__ << endl;
  }
};
template<class T>
struct Functor2<typename S1_t<T>::template inner_t_x<T>>
{
  void operator()() 
  {
    cout << "Functor2 PASS: " << __PRETTY_FUNCTION__ << endl;
  }
};

template<class T>
void eval()
{
  Functor1<T>{}();
  Functor2<T>{}();
}

int main()
{
  eval<S1_t<Bogus>::inner_t>();
  return 0;
}

$ clang++ repro.cpp -std=c++11 -Wall && ./a.out
Functor1 PASS: void Functor1<S1_t<Bogus>::inner_t_x<Bogus> >::operator()()
Functor2 FAIL: void Functor2<S1_t<Bogus>::inner_t_x<Bogus> >::operator()() [T = S1_t<Bogus>::inner_t_x<Bogus>]
给出正确的输出

Functor1 PASS: void Functor1<S1_t<Bogus>::inner_t_x<Bogus> >::operator()()
Functor2 PASS: void Functor2<S1_t<Bogus>::inner_t_x<Bogus> >::operator()() [T = S1_t<Bogus>::inner_t_x<Bogus>]
Functor1过程:无效Functor1::operator()()
Functor2过程:无效Functor2::运算符()[T=S1\u T::inner\u T\u x]
但在我的用例中,这不是选项。

类型名称S1\t::…
在部分专门化中是不可推断的

使用
internal\u t
而不是
internal\u t\u x
时,出现了一个更清楚的错误:

main.cpp:41:8:错误:部分专门化中无法推断模板参数:
结构函子2
^
main.cpp:41:8:注:“T”
main.cpp:41:8:警告:类模板部分专门化包含无法推导的模板参数;这种局部专门化永远不会被使用

永远不会使用
函数2
的专门化。编译器可能会发出警告,但在您的情况下不会。它不可推断的原因很简单:想象你后来添加了

struct Hogus;

template<>
struct S1_t<Hogus>
{
  template <typename U>
  using inner_t_x = S1_t<Bogus>::inner_t_x<Bogus>;
};
struct Hogus;
模板
结构S1\u t
{
模板
使用internal\u t\u x=S1\u t::internal\u t\u x;
};

然后
S1_t::internal_t_x
S1_t::internal_t_x
将是相同的类型。因此,
Functor2
的部分特化中的模板推导可以产生
T=Bogus
T=Hogus
。因此,在任何情况下都无法明确推断

为什么
模板结构Functor1
中没有类型?也许这只是一些我不知道的特殊语法,但它看起来很奇怪。引用(相对于n4567):[temp.decrete.type]p5和p6“当以包含非推断上下文的方式指定类型名时,构成该类型名的所有类型也都是非推断的。”换句话说,绝对没有办法推导出T,对吗?如果是这样的话,我会被缺乏编译器警告的想法误导,认为类型推断是在::inner_t_x上完成的。感谢一个生动的例子,它突然变得非常清楚。那么,有什么方法可以毫不含糊地推导出T型呢?我的直觉是没有,但我不是100%确定。我不认为有任何方法可以推断嵌套类型的外部和内部。很抱歉
main.cpp:41:8: error: template parameters not deducible in partial specialization:

 struct Functor2<typename S1_t<T>::inner_t>

        ^

main.cpp:41:8: note:         'T'

main.cpp:41:8: warning: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used
struct Hogus;

template<>
struct S1_t<Hogus>
{
  template <typename U>
  using inner_t_x = S1_t<Bogus>::inner_t_x<Bogus>;
};