为什么限定名称是非受限的上下文

时间:2016-10-11 14:39:13

标签: c++ templates

任何人都可以在下面解释我

一些构造不是推导出的上下文

  

合格的类型名称。像Q<T>::X这样的类型名称永远不会被使用   例如,推导出模板参数T

     

非类型表达式,不仅仅是非类型参数。一种   例如,S<I+1>之类的名称永远不会用于推断I。也不   将T通过匹配类型参数来推断   int(&)[sizeof(S<T>)]

     

这些限制因为扣除而不足为奇   一般而言,它不是唯一的(甚至是有限的)。

为什么T中的Q<T>::X无法推断出来?以及为什么int(&)[sizeof(S<T>)]称为非类型表达式,即使它具有类型参数。

内容取自:&#34; C ++模板完整指南&#34;

EX(来自书)

template <int N>
class X {
public:
   typedef int I;
   void f(int) {}
};

template<int N>
void fppm(void (X<N>::*p)(X<N>::I));

int main()
{
   fppm(&X<33>::f); // fine: N deduced to be 33
}
  

在功能模板fppm()中,子结构X<N>::I是一个   无理性的背景。

修改

  

我已经阅读了一些引发另一个问题的答案

     

template<typename T> void(T p1,typename foo<T>::subtype P2)

     

在上述减速中,如果foo<T>没有推断出哪个子类型   编译器将选择p2

EDIT2

  

我正在尝试下面

#include <iostream>
#include <cstring>
template <typename T>
struct foo{
    using type=int;
    void print(type a){
        std::cout<<a<<"\n";
    }
};
template<>
struct foo<float>{
    using type=float;
    void print(type a){
            std::cout<<a<<"\n";
        }
};

template<typename T2>
void test(foo<T2> o,typename foo<T2>::type p){
    o.print(p);
}

 int main(){
     foo<float> o;
     test(o,1.2);
 }

很傻但我想知道在test(o,1.2)之后T2的类型是什么

1 个答案:

答案 0 :(得分:3)

考虑以下示例:

template <typename T>
struct C
{
    using type = T;
};

template <>    // specialization
struct C<float>
{
    using type = int;   // oops
};

template <>    // another specialization
struct C<char>
{
    char type;   // type is not even a type now
};


template <typename T>
void foo( typename C<T>::type x ) {}

template <typename T>
void foo( C<T>, typename C<T>::type x ) {}

int main()
{
    // foo(3);   // there are two parameter T (int & float)
                 // that both would deduce to int for type.
                 // Which T should the compiler chose?
    foo<int>(3);   // explicitly naming the type works.
    foo<float>(3);

    foo( C<int>{}, 3);          // works
    foo( C<float>{}, 3);        // works
    // foo( C<char*>{}, 3);     // doesn't work, conflicting types
    foo( C<char*>{}, "hello");  // works
}

这个例子应该清楚为什么这个结构是不可能的。它易于构造模糊,这对于编译器来说是无法解决的。