我有这个测试用例:
struct A{ protected: A(){} };
struct B: A{};
struct C: A{ C(){} };
struct D: A{ D() = default; };
int main(){
(void)B{};
(void)C{};
(void)D{};
}
Run Code Online (Sandbox Code Playgroud)
gcc和clang都用C++ 11和C++ 14模式编译它.两者都在C++ 17模式下失败:
$ clang++ -std=c++17 main.cpp
main.cpp:7:10: error: base class 'A' has protected default constructor
(void)B{};
^
main.cpp:1:22: note: declared protected here
struct A{ protected: A(){} };
^
main.cpp:9:10: error: base class 'A' has protected default constructor
(void)D{};
^
main.cpp:1:22: note: declared protected here
struct A{ protected: A(){} };
^
2 …Run Code Online (Sandbox Code Playgroud) 请考虑以下示例:
#include <iostream>
#include <string>
#include <utility>
template <typename Base> struct Foo : public Base {
using Base::Base;
};
struct Bar {
Bar(const Bar&) { }
Bar(Bar&&) = delete;
};
int main() {
std::cout << std::is_move_constructible<Bar>::value << std::endl; // NO
std::cout << std::is_move_constructible<Foo<Bar>>::value << std::endl; // YES. Why?!
}
Run Code Online (Sandbox Code Playgroud)
尽管基类是不可移动构造的,为什么编译器会生成移动构造函数?
这是标准还是编译器错误?是否有可能"完美地传播"将构造从基础移动到派生类?
众所周知,标量数组的缺少初始值设定值默认为零.
int A[5]; // Entries remain uninitialized
int B[5]= { 0 }; // All entries set to zero
Run Code Online (Sandbox Code Playgroud)
但是这(下面)保证了吗?
int C[5]= { }; // All entries set to zero
Run Code Online (Sandbox Code Playgroud) 考虑
#include <iostream>
#include <type_traits>
template <class T, class ARG_T = T&>
T foo(ARG_T v){
return std::is_reference<decltype(v)>::value;
}
int main() {
int a = 1;
std::cout << foo<int>(a) << '\n';
std::cout << foo<int, int&>(a) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我希望两种情况下的输出均为1。但在第一种情况下为0:与默认值class ARG_T = T而不是一致class ARG_T = T&。
我想念什么?
c++ templates function-templates template-argument-deduction argument-deduction
下面是一个代码片段,可以在vs2015中编译和运行而不会出错
#include<iostream>
using namespace std;
class A {
public:
A(int b) :k(b) {}//second time
const int k = 666;//first time
};
int main() {
A a(555);
cout << a.k << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是555.但据我所知,const对象应该只初始化一次,之后值不可修改.
我很困惑.不是const auto ch = unsigned char{'p'};一个完全有效的初始化表达式?所有三个主要编译器都无法使用几乎相同的错误消息进行编译:
错误:预期'('用于函数式转换或类型构造
交换花括号('p')没有任何变化.但是,它确实在没有signedor unsigned关键字的情况下编译.
我的一个朋友给我看了一个 C++20 程序:
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
~A() {std::cout << "~A()\n";}
};
struct B
{
const A &a;
};
int main()
{
B x({});
std::cout << "---\n";
B y{{}};
std::cout << "---\n";
B z{A{}};
std::cout << "---\n";
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 中,它打印:
A()
~A()
---
A()
---
A()
---
~A()
~A()
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/ce3M3dPeo
因此,A在 y 和 z 情况下,的寿命会延长。
在 Visual Studio 中,结果是不同的:
A()
~A()
---
A()
---
A()
~A()
---
~A()
Run Code Online (Sandbox Code Playgroud)
所以A只有在 y …
之间有什么区别?
auto x = vector<int>();
Run Code Online (Sandbox Code Playgroud)
和
vector<int> x;
Run Code Online (Sandbox Code Playgroud)
这两个声明是否相等,或者运行时复杂度是否有所不同?
我正在阅读新C++概述(C++ 11/14)(仅限PDF),在幻灯片288中它给出了一个实现std::forward:
template<typename T> // For lvalues (T is T&),
T&& std::forward(T&& param) // take/return lvalue refs.
{ // For rvalues (T is T),
return static_cast<T&&>(param); // take/return rvalue refs.
}
Run Code Online (Sandbox Code Playgroud)
然后在文本中给出另一个实现:
通常的std :: forward实现是:
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
T&& forward(typename identity<T>::type&& param)
{ return static_cast<identity<T>::type&&>(param); }
Run Code Online (Sandbox Code Playgroud)
有什么不同?为什么后者通常是实施?
我尝试使用默认模板参数编写此函数:
template<typename A, typename B>
void func(int i1, int i2, A a, B b = 123){
...
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我可以这样称呼它:func(1, 2, 3)编译器应该从默认值推断出类型B,int但我得到了no instance of overloaded function。
在这种情况下,C++ 构造是否不正确并且编译器无法推断出类型?
c++ templates default default-arguments template-argument-deduction