\n\n仅当类型推导失败时才考虑这些替代方案 ( [temp.deduct.call]/4 )。如果它们产生多个\n可能的推导 A,则类型推导失败。[ 注意:如果模板参数未在函数模板的任何函数参数中使用,或者仅在非推导上下文中使用,则无法从函数调用中推导其对应的模板参数\n并且必须显式指定模板参数。\xe2\x80\x94 尾注]
\n
我的问题:
\n请用触发此案例的示例来支持答案。
\n我从cppreference发现了这个例子:
\n...\n\nstruct T3\n{\n int mem1;\n std::string mem2;\n T3() {} // user-provided default constructor\n}\n\n...\nRun Code Online (Sandbox Code Playgroud)\n此示例清楚地表明给定的构造函数是用户提供的构造函数,因为它在第一个声明中没有显式默认或删除;根据 [dcl.fct.def.default]/5:
\n\n\n[..] 如果函数是用户声明的并且在其第一次声明时未\n显式默认或删除,则该函数是用户提供的 [..]
\n
现在,根据 [dcl.init.aggr]/1
\n\n\n聚合是一个数组或一个类(第 11 条)
\n\n
\n- (1.1) \xe2\x80\x94 没有用户声明或继承的构造函数 (11.4.5),
\n- (1.2) \xe2\x80\x94 没有私有或受保护的直接非静态数据成员 (11.8),
\n- (1.3) \xe2\x80\x94 无虚函数 (11.7.3),以及
\n- (1.4) \xe2\x80\x94 无虚拟、私有或受保护的基类 (11.7.2)。
\n
看来我的类满足上述所有要求,成为一个聚合,包括点 (1.1),因为给定的构造函数不是用户声明的。
\n那么为什么下面的代码格式错误(在带有 c++20 标志的 g++12.2 上测试):
\nstatic_assert(std::is_aggregate<T3>::value); // fail\nRun Code Online (Sandbox Code Playgroud)\n为什么静态断言失败?
\n这是我之前的问题的后续问题:为什么成员函数返回非静态数据成员而不是核心常量表达式?
该问题中提到的示例的简化版本是:
struct S {
const bool x = true;
constexpr bool f() { return x; }
};
int main() {
S s{};
static_assert(s.f()); // error: 's' is not a constexpr;
}
Run Code Online (Sandbox Code Playgroud)
标准中适用的措辞是 N4861:[expr.const]/(5.1):
表达式
E是核心常量表达式E,除非 的计算遵循抽象机 ([intro.execution]) 的规则,将计算以下其中一项:
- (5.1) ([expr.prim.this]),但作为 的一部分进行求值的函数 ([dcl.constexpr])
this除外;constexprE
据我可以解析,表达式E是并且s.f()它的计算结果是返回一个非静态成员。但这属于“例外”部分:成员函数是 constexpr 函数,它作为. 如果我解析正确,我期望得到常量表达式并且断言成功。thiss.f()this->xs.S::f()s.f()s.f()
s但是,该项目符号并未指定必须是常量表达式的要求。我不明白为什么声明sasconstexpr会编译程序,即使没有在此项目符号中定义的s要求constexpr。
我只是在我的示例中应用了措辞(5.1),但我看不到 …
根据我的理解,我知道当一个对象被实例化时,构造函数被调用一次。但我不明白为什么两个构造函数都被调用而只有一个对象被实例化
#include <iostream>
using namespace std;
#define print(me) cout << me << endl;
class A
{
public:
A() { print("default called"); }
A(int x) { print("paramterized called"); }
};
int main()
{
A a;
a = A(10);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到输出:默认调用参数化调用