相关疑难解决方法(0)

gcc和clang在运算符重载解析期间隐式实例化模板参数

考虑以下代码:

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)

c++ gcc templates clang

32
推荐指数
1
解决办法
1090
查看次数

何时将模板参数包推导出为空?

考虑以下示例(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...一旦尝试并失败,似乎没有退缩为空的迹象。

  • 这是故意行为吗?如果是这样,为什么?
  • 如果是这样,是否打算用“不以其他方式推论”的措辞来指明这种行为?(,这意味着仅当包未在任何推论上下文中出现时,才会发生空的回退)
  • 如果是这样,这个措词是否足够清楚?似乎“不以其他方式推论”的替代读法是“未进行推论,或试图进行推论而失败”。

c++ templates language-lawyer variadic-templates

14
推荐指数
1
解决办法
197
查看次数