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{}
等?@BenVoigtC{}
它会创建一个对象吗?是的,我通过添加括号{/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
}