我正在浏览我为学校项目编写的一些代码,经过仔细检查,我觉得很奇怪.我有一个类似下面的类:
class Foo {
public:
Foo(std::string s) : _s(s) {}
private:
std::string _s;
};
int main() {
std::string str = "Hiyo";
std::vector<Foo> f;
f.push_back(str); // Compiles. Weird to me though.
f.push_back(Foo(str)); // Predictably, this compiles as well.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么第一次调用push_back有效语句,即使str不是Foo?
我在学习C++时遇到了一个问题,其中函数中的局部变量被传递给另一个函数中具有相同名称的局部变量,这两个函数都在main()中运行.
当这个运行时,
#include <iostream>
using namespace std;
void next();
void again();
int main()
{
int a = 2;
cout << a << endl;
next();
again();
return 0;
}
void next()
{
int a = 5;
cout << a << endl;
}
void again()
{
int a;
cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)
它输出:
2
5
5
Run Code Online (Sandbox Code Playgroud)
我期望again()会说null或0,因为'a'再次在那里声明,但它似乎使用了'a'在next()中赋值的值.
为什么next()将局部变量'a'的值传递给again()如果'a'再次在again()中声明?
我想知道关于下面这段代码的标准是什么.可以string临时对象的析构函数调用之前执行printPointer?
ps VS2010编译器不会抱怨此代码并且工作正常.
void printPointer(const string* pointer)
{
cout << *pointer << endl;
}
const string* func(const string& s1)
{
return &s1;
}
int main()
{
printPointer(func("Hello, World!!!"));
}
Run Code Online (Sandbox Code Playgroud) 以下代码编译并运行正常.
void foo() {
}
template <typename T, typename... Args>
void foo(T x, Args... args) {
cout << x << endl;
foo(args...);
}
// inside main()
foo(1,1,1);
Run Code Online (Sandbox Code Playgroud)
这个其他代码不编译:
void foo() {
}
template <typename... Args, typename T>
void foo(Args... args, T x) {
foo(args...);
cout << x << endl;
}
// inside main()
foo(1,1,1);
Run Code Online (Sandbox Code Playgroud)
编译器说调用没有匹配函数,foo(1,1,1)并且说它foo(Args... args, T x)是候选函数,但模板参数推导/替换失败,因为候选者需要1个参数,但提供了3个参数.
这种情况是否存在任何编译器无法处理的歧义?这个编译错误对我来说似乎不合逻辑.也许这与C++标准有意无关?
默认模板参数是否可以以不从右开始的方式使用"默认值"?
标准是什么?
编译器将如何解释?
例如,我很惊讶这段代码有效.
#include <iostream>
using namespace std;
template <bool T=true, class U> //"default" from LEFT-most parameter
void f(U u){
if(T){ cout<<true;}
else cout<<false;
}
int main() {
auto x = []( ){ };
f(x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里查看现场演示:https://ideone.com/l6d9du
我有一个类Item,它定义了自己的operator new和operator delete,如下所示:
class Item
{
public:
Item(const std::string &s):msg(s)
{
std::cout<<"Ctor: "<<msg<<std::endl;
}
static void* operator new(size_t size, int ID, const std::string &extra)
{
std::cout<<"My Operator New. ID/extra: "<<ID<<"/"<<extra<<std::endl;
return ::operator new(size);
}
static void operator delete(void* p)
{
std::cout<<"My Operator Delete"<<std::endl;
return;
}
~Item()
{
std::cout<<"Destructor: "<<msg<<std::endl;
}
void Print()
{
std::cout<<"Item::msg: "<<msg<<std::endl;
}
private:
std::string msg;
};
Run Code Online (Sandbox Code Playgroud)
我使用placement new创建了这种类型的对象,然后删除如下:
int main()
{
Item *pI=new(1,"haha")Item("AC Milan");
std::cout<<"before delete"<<std::endl;
delete pI;
std::cout<<"after delete"<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是: …
所以我在这里读到:https://stackoverflow.com/a/598150/2642059这是非法的:
foo(i++, i++);
Run Code Online (Sandbox Code Playgroud)
但我相信这是因为没有强制序列,我理解的是初始化列表的情况.这个法律代码也是如此吗?
const int foo[] = { i++, i++ };
Run Code Online (Sandbox Code Playgroud) Visual C++ 2017和gcc 5.4 在此代码段中产生但不是conversion from 'const unsigned char' to 'const float' requires a narrowing conversion警告:Line BLine A
#include <iostream>
int main() {
const unsigned char p = 13;
const float q = p; // Line A
std::cout << q << '\n';
const unsigned char c[3] = {0, 1, 255};
const float f[3] = {c[2], c[0], c[1]}; // Line B
for (auto x:f)
std::cout << x << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这个警告有效吗?为什么Line B治疗不同于Line A?
例如,如果我有
#include <type_traits>
struct OwnershipReceiver
{
template <typename T,
class = typename std::enable_if
<
!std::is_lvalue_reference<T>::value
>::type
>
void receive_ownership(T&& t)
{
// taking file descriptor of t, and clear t
}
};
Run Code Online (Sandbox Code Playgroud)
海报使用!std::is_lvalue_reference而不是立即更明显std::is_rvalue_reference.我已经在我自己的代码中验证了这一点,前者有效,后者没有.
任何人都可以解释为什么明显不起作用?
我正在升级现有的旧代码以使用 VS 2019 *,在代码中我有以下函数在返回行失败:
int foo(const char *fn) const
{
ofstream out(fn,ios::binary);
if (out)
{
//...
}
return out!=0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
错误 C2678 二进制“!=”:未找到采用“std::ofstream”类型左侧操作数的运算符(或没有可接受的转换)
原始诗人的意图是什么,解决问题的最佳方法是什么?
*此代码在 VS 2010 上编译成功。
c++ ofstream visual-c++ implicit-conversion visual-studio-2019
c++ ×10
c++11 ×3
templates ×3
destructor ×2
visual-c++ ×2
arguments ×1
enable-if ×1
gcc ×1
gcc-warning ×1
ofstream ×1
sequencing ×1
temporary ×1