在保证复制省略的世界中,构造函数实例化

6
考虑以下示例:
template <typename T>
using type = typename T::type;

template <typename T>
struct A
{
    A(type<T>);
};

A<int> f();
A<int> g() { return f(); }

由于int没有嵌套的type typedef,所以既不gcc也不clang编译此代码。但是为什么会实例化构造函数呢?f()是与g()返回类型相同的prvalue,甚至不应该有移动操作。是什么导致我们实例化了错误的构造函数?


复制省略仅省略实际的复制本身。如果没有发生复制省略,代码仍必须符合其通常需要符合的所有规则。代码被编译为好像没有进行复制省略一样,但复制本身被省略了。 - Sam Varshavchik
3
@SamVarshavchik 这不是真的。 - Barry
2
@SamVarshavchik:他谈论的是保证省略,它没有这样的要求。没有需要被省略的复制。 - Nicol Bolas
1个回答

9
构造函数有些误导性。如果是任何其他成员函数,情况也是一样的。
template <typename T>
struct A
{
    void foo(type<T>); // Same error
};

这是因为[temp.inst]/2的缘故。

类模板特化的隐式实例化会导致声明的隐式实例化,但不会导致类成员函数的定义、默认参数或 noexcept-specifiers 的隐式实例化。

声明被实例化,所以 type<T> 必须是格式良好的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接