我有以下测试程序:
#include <iostream>
#include <type_traits>
#include <utility>
template<typename Ty, std::size_t N>
void foo(Ty (&&)[N])
{
std::cout << "Ty (&&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}
template<typename Ty, std::size_t N>
void foo(Ty (&)[N])
{
std::cout << "Ty (&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}
template<typename Ty>
using id = Ty;
int main()
{
std::cout.setf(std::cout.boolalpha);
foo(id<int[]>{1, 2, 3, 4, 5});
foo(id<int const[]>{1, 2, 3, 4, 5}); // <-- HERE.
int xs[]{1, 2, 3, 4, 5};
foo(xs); …
Run Code Online (Sandbox Code Playgroud) 为什么与数组一起使用const
和constexpr
使用时有区别?
int const xs[]{1, 2, 3};
constexpr int ys[]{1, 2, 3};
int as[xs[0]]; // error.
int bs[ys[0]]; // fine.
Run Code Online (Sandbox Code Playgroud)
我希望既xs[0]
和ys[0]
是常数表达式,但只有后者被视为这样.
如果我们有一个widget.hpp
包含以下内容的头文件:
constexpr int foo = 10;
struct widget
{
int bars[foo];
};
Run Code Online (Sandbox Code Playgroud)
...并且我们有两个源文件生成的两个翻译单元,这两个源文件都只包括widget.hpp
,这是否违反了一个定义规则(更具体地说,是否foo
违反了一个定义规则)?
foo
有内部联系,但它也是一个不变的表达.从我在C++ 11标准中阅读3.2.6(我将在下面引用)中可以看出,如果需求#2不仅仅指静态数据成员,那么它就是格式良好的.
3.2.6要求#2:
在D的每个定义中,根据3.4查找的相应名称,应指在D的定义中定义的实体,或者在重载决议(13.3)之后和部分模板专业化匹配之后应引用同一实体(14.8) .3),除非名称可以引用具有内部链接或没有链接的非易失性const对象,如果该对象在D的所有定义中具有相同的文字类型,并且该对象使用常量表达式(5.19)初始化,并且该对象没有使用odr,并且该对象在D的所有定义中具有相同的值
如果你正在使用NVI,那么编译器是否可以虚函数调用函数?
一个例子:
#include <iostream>
class widget
{
public:
void foo() { bar(); }
private:
virtual void bar() = 0;
};
class gadget final : public widget
{
private:
void bar() override { std::cout << "gadget\n"; }
};
int main()
{
gadget g;
g.foo(); // HERE.
}
Run Code Online (Sandbox Code Playgroud)
在标记的行上,编译器可以将调用虚拟化为bar
?