考虑以下代码:
struct A; // incomplete type
template<class T>
struct D { T d; };
template <class T>
struct B { int * p = nullptr; };
int main() {
B<D<A>> u, v;
u = v; // doesn't compile; complain that D<A>::d has incomplete type
u.operator=(v); // compiles
}
Run Code Online (Sandbox Code Playgroud)
演示.由于u.operator=(v)
编译但u = v;
没有,在后一个表达式的重载解析期间,编译器必须已经隐式实例化D<A>
- 但我不明白为什么需要实例化.
为了使事情更有趣,这段代码编译:
struct A; // incomplete type
template<class T>
struct D; // undefined
template <class T>
struct B { int * p …
Run Code Online (Sandbox Code Playgroud) 考虑以下示例(Coliru链接):
template <class... T> struct S { using type = int; };
template <class... T>
void f(typename S<T...>::type) {
static_assert(sizeof...(T) == 0);
}
template <class... T>
void g(typename S<T...>::type, S<T...>*) {}
int main() {
f(42);
g(42, nullptr);
}
Run Code Online (Sandbox Code Playgroud)
GCC和Clang都对致电感到满意f
,但对的致电并不满意g
。
在对的调用中f
,尽管T...
出现在非推导上下文中,但最终被推导为空。这似乎是由于[temp.arg.explicit] / 4造成的:
...否则未推断出的尾随模板参数包([temp.variadic])将被推断为模板参数的空序列。...
g
但是,在对的调用中,在推断的上下文中T...
另外出现的事实(这导致尝试尝试并失败)似乎导致g
变得不可行。T...
一旦尝试并失败,似乎没有退缩为空的迹象。