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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/145.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 - Fatal编程技术网

C++ 为什么限定名是非派生上下文

C++ 为什么限定名是非派生上下文,c++,templates,C++,Templates,有人能给我解释一下下面的内容吗 一些结构不是在上下文中推导出来的 限定类型名。像Q::X这样的类型名永远不会用于 例如,推断模板参数T 不只是非类型参数的非类型表达式。A型 例如,像S这样的名称永远不会用于推断I。也不 T是否通过匹配类型的参数来推导 int(&)[sizeof(S)] 这些限制并不奇怪,因为 一般来说,它不是唯一的(甚至是有限的) 为什么Q::X中的T不能推导?为什么int(&)[sizeof(S)]被称为非类型表达式,即使其中包含类型参数 内容取自:“C++模板完整指南” E

有人能给我解释一下下面的内容吗

一些结构不是在上下文中推导出来的

限定类型名。像
Q::X
这样的类型名永远不会用于 例如,推断模板参数
T

不只是非类型参数的非类型表达式。A型 例如,像
S
这样的名称永远不会用于推断
I
。也不
T
是否通过匹配类型的参数来推导
int(&)[sizeof(S)]

这些限制并不奇怪,因为 一般来说,它不是唯一的(甚至是有限的)

为什么
Q::X
中的
T
不能推导?为什么
int(&)[sizeof(S)]
被称为非类型表达式,即使其中包含类型参数

内容取自:“C++模板完整指南”

EX(来自书本)


这很愚蠢,但我想知道
测试(o,1.2)
后T2的类型是什么,请考虑以下示例:

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
}
模板
结构C
{
使用类型=T;
};
模板//专门化
结构C
{
使用type=int;//oops
};
模板//另一个专门化
结构C
{
char type;//type现在甚至不是类型
};
模板
void foo(类型名C::类型x){}
模板
void foo(C,typename C::type x){}
int main()
{
//foo(3);//有两个参数T(int和float)
//这两种类型都会推断为int。
//编译器应该选择哪个T?
foo(3);//显式命名类型有效。
傅(3);
foo(C{},3);//作品
foo(C{},3);//作品
//foo(C{},3);//不工作,类型冲突
foo(C{},“hello”);//工作
}

这个例子应该说明为什么这个构造是不可能的。很容易构造编译器无法解决的歧义。

我不明白,你能给我们举个例子吗?在你的EDIT2示例中,
T2
是从
o
参数推导出来的,但不是从
p
参数推导出来的。因此推断成功,然后到处替换
T2=float
,计算
typename foo::type
得到
float
@aschepler如果它是从
o
arg推断出来的,那么
T2
应该是
foo
而不仅仅是
float
不是?不,编译器将参数类型
foo
与参数类型
foo
进行比较,得出为了使它们相等,
T2
必须是
float
。如果无法在
foo
中推断类型
t
,如何获得相应的类型。@FallingFromBed:通过在调用站点显式指定
t
<代码>foo(float{})可以正常工作。在main内部,也许你的意思只是
int{}
float{}
char{}
,而不是
C{}
等?@BenVoigt
C{}
它会创建一个对象吗?是的,我通过添加括号
{/code>创建了一个
C
类型的对象实例。
#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);
 }
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
}