小编R S*_*ahu的帖子

保证省略和链接函数调用

假设我有以下类型:

struct X {
    X& operator+=(X const&);
    friend X operator+(X lhs, X const& rhs) {
        lhs += rhs;
        return lhs;
    }
};
Run Code Online (Sandbox Code Playgroud)

我有声明(假设所有命名变量都是类型的左值X):

X sum = a + b + c + d;
Run Code Online (Sandbox Code Playgroud)

在C++ 17中,我对这个表达式执行的副本和移动有多少保证?那么无保障的省略呢?

c++ copy-elision c++17

18
推荐指数
2
解决办法
522
查看次数

如何基于每个成员覆盖类作用域__declspec(dllexport)注释?

在ELF目标上,如果我已经通过类似的声明class Foo给予它default可见性class __attribute__((visibiility("default"))) Foo,那么我可以选择性地default通过明确地用它们注释来使类的某些成员免于可见性__attribute__((visibility("hidden")).这对于不应构成ABI一部分的内联方法非常有用,因此如果在构建库定义时发出class Foo它们,则不会导出它们,或者其中的private成员或类型class Foo也不应构成其ABI的一部分.

但是,在Windows上,似乎没有办法实现这一目标.虽然unadorned class Foo自动私有DLL,但一旦被装饰为class __declspec(dllexport) Foo,整个类现在都是dllexport,并且似乎没有可以选择性地覆盖__dllexport特定成员状态的关联注释.标记选择"不用于导出"成员__declspec(dllimport)显然是错误的.

是否有其他方法可以阻止类作用域__dllexport应用于某些类成员和/或类型?

为了使这更具体,我想说的,并且可以说,当使用ELF注释时:

class __attribute__((visibility("default"))) Foo {
public:
    Foo(); // OK, default visibility

    // Don't let inlines join the ABI
    __attribute__((visibility("hidden")) inline void something() { ... }

private:
    // Don't let private members join the ABI
    __attribute__((visibility("hidden")) void _internal();

    // Our pImpl type …
Run Code Online (Sandbox Code Playgroud)

c++ dll visibility elf visual-c++

17
推荐指数
1
解决办法
431
查看次数

"A Tour of C++"中的错误代码或不兼容的编译器?

我在"A Tour of C++"中看到了以下函数,第12页:

int count_x(char const* p, char x)
{
   int count = 0;
   while (p)
   {
      if (*p == x) ++count;
      ++p;
   }
   return count;
}
Run Code Online (Sandbox Code Playgroud)

这条线while (p)听起来不对我.我以为它应该是while (*p).但是,不想过于放肆,我用下面的代码测试了这个函数.

int main(int argc, char** argv)
{
   char* p = argv[1];
   char x = argv[2][0];
   int count = count_x(p, x);

   std::cout
      << "Number of occurences of "
      << x << " in " << p << ": " << count << std::endl;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行该程序时,它退出了 …

c++ g++ c++11

15
推荐指数
1
解决办法
988
查看次数

通过获取对子对象的引用来延长临时对象的生命周期

cppreference.comC++ 11标准使用的语言之间存在细微差别,关于临时对象的生命何时延长(强调我的).

来自cppreference.com:

每当引用绑定到临时或临时的基础子对象时,临时的生命周期将延长以匹配引用的生命周期,

来自C++ 11标准:

第二个上下文是引用绑定到临时的.绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:

根据标准,主题可以是成员主题,基类主题或数组元素.

如果我们严格按照以下示例代码中的标准的措辞

struct Foo 
{
   Foo() : a(10), b(20) {}
   ~Foo() { std::cout << "In Foo::~Foo()\n"; }
   int a;
   int b;
};

Foo getFoo()
{
   return Foo();
}

void testFoo1()
{
   int const& r = getFoo().a;
   std::cout << "In testFoo1()\n";
   (void)r; // Shut up the compiler
}
Run Code Online (Sandbox Code Playgroud)

返回的对象getFoo()的生命周期应该延长参考的生命周期.但是,一个简单的测试似乎表明它没有.

标准使用的措辞是否有缺陷?
编译器是否不符合要求?
cppreference.com使用的措词是否有缺陷?

更新

cppreference.com上使用的语言已更新为(强调我的):

每当引用绑定到临时或子对象时 …

c++ language-lawyer temporary-objects c++11

15
推荐指数
1
解决办法
256
查看次数

在类中引入的类名不被视为嵌套类名

采取这些类定义:

班级定义1:

struct A 
{
   struct B* m_b;
};
Run Code Online (Sandbox Code Playgroud)

班级定义2:

struct A 
{
   struct B;
   B* m_b;
};
Run Code Online (Sandbox Code Playgroud)

类定义都应该声明B为嵌套类.至少,通过阅读C++ 11标准草案中的以下内容,我的想法是:

9.1/2类声明将类名引入声明它的作用域中,并在封闭作用域中隐藏该名称的任何类,变量,函数或其他声明(3.3).如果一个类名称被在一个范围内声明,其中的变量,函数,或具有相同名称的枚举还声明,那么当两个声明是在范围内,类可以被称为仅使用阐述型说明符 `

但是,g ++ 4.8.2对它们的处理方式不同.在第一个定义中,它将其视为B同类的类A.

以下程序成功构建:

struct A 
{
   struct B* m_b;
};

void myfun(const B& b )
{
}

int main()
{
   A a;
   myfun(*a.m_b);
}
Run Code Online (Sandbox Code Playgroud)

而以下程序没有:

struct A 
{
   struct B;
   B* m_b;
};

void myfun(const B& b )
{
}

int main()
{
   A a;
   myfun(*a.m_b);
}
Run Code Online (Sandbox Code Playgroud)

我理解为什么第二个程序没有编译,但我不明白为什么第一个程序是成功构建的.

我在标准的解释中遗漏了什么吗?

编译第一个程序时g …

c++ g++ c++11

13
推荐指数
1
解决办法
824
查看次数

为什么datetime.now()和datetime.today()在我的电脑上显示UTC时间而不是当地时间?

datetime.now()并且datetime.today()在我的计算机上以UTC返回时间,即使文档说他们应该返回当地时间.

这是我运行的脚本:

#!/usr/bin/python

import time
import datetime

if __name__ == "__main__":
   print(datetime.datetime.now())
   print(datetime.datetime.today())
   print(datetime.datetime.fromtimestamp(time.time()))
Run Code Online (Sandbox Code Playgroud)

这是输出:

2017-11-29 22:47:35.339914
2017-11-29 22:47:35.340399
2017-11-29 22:47:35.340399
Run Code Online (Sandbox Code Playgroud)

date之后运行的输出是:

Wed, Nov 29, 2017  3:47:43 PM
Run Code Online (Sandbox Code Playgroud)

为什么我的安装返回UTC时间?
我该怎么办才能让这些功能返回当地时间?

PS我们在MST,这是UTC-7.

PS 2我意识到有一些方法可以将UTC时间转换为本地时间,例如在使用python标准库将python UTC datetime转换为本地日期时所解释的那些方法?.但是,我试图了解基本问题的原因,而不是寻找一种方法来修补我自己的代码中的问题.


回应@jwodder的评论:

执行的输出

print(time.altzone)
print(time.timezone)
print(time.tzname)
Run Code Online (Sandbox Code Playgroud)

是:

-3600
0
('Ame', 'ric')
Run Code Online (Sandbox Code Playgroud)

python datetime python-3.x

12
推荐指数
1
解决办法
852
查看次数

使用constexpr静态成员变量的奇怪行为

这是对未定义的静态constexpr char [] []的引用的后续问题.

以下程序构建并运行良好.

#include <iostream>

struct A {
   constexpr static char dict[] = "test";

   void print() {
      std::cout << A::dict[0] << std::endl;
   }
};

int main() {
   A a;
   a.print();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我A::print()改为:

   void print() {
      std::cout << A::dict << std::endl;
   }
Run Code Online (Sandbox Code Playgroud)

我在g ++ 4.8.2中收到以下链接器错误.

/tmp/cczmF84A.o: In function `A::print()':
socc.cc:(.text._ZN1A5printEv[_ZN1A5printEv]+0xd): undefined reference to `A::dict'
collect2: error: ld returned 1 exit status

可以通过添加一行来解决链接器错误:

constexpr char A::dict[];
Run Code Online (Sandbox Code Playgroud)

在课堂定义之外.

但是,我不清楚为什么使用数组的一个成员在使用数组时不会导致链接器错误导致链接器错误.

c++ c++11

11
推荐指数
1
解决办法
402
查看次数

为什么返回对字符串文字的引用是对临时的引用?

常规字符串字符串文字具有以下定义:

普通字符串文字和UTF-8字符串文字也称为窄字符串文字.窄字符串文字的类型为"n const char数组",其中n是下面定义的字符串大小,并且具有静态存储持续时间(3.7).

我假设因为它具有静态存储持续时间并且它们通常被放置在ROM中,如果有一个悬挂引用它真的没什么大不了的.以下代码发出警告

const char* const & foo()
{
    return "Hello";
}
// warning: returning reference to temporary [-Wreturn-local-addr]
Run Code Online (Sandbox Code Playgroud)

但即使没有static关键字,这也没关系

const char* const & foo()
{
    const char* const & s = "Hello";
    return s;
}
Run Code Online (Sandbox Code Playgroud)

那两者有什么区别?

c++ temporary-objects

11
推荐指数
2
解决办法
1420
查看次数

移动其内容后调用vector.resize(0)是否安全

换句话说是以下代码声音(定义的行为,便携式,...)

   std::vector<int> vec(100,42);
   std::vector<int> other = std::move(vec);
   vec.resize(0);//is this sound

   //using vec like an empty vector
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

11
推荐指数
2
解决办法
688
查看次数

数据成员'vec'不能是成员模板

我在标题中有以下两行,以声明包含模板的向量:

template <class t>
    std::vector <t> vec;
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:数据成员'vec'不能是成员模板我做错了什么?编辑:我不知道我被理解正确,我试图声明一个包含模板的向量,我知道这可以完成,因为可以有以下内容:

template <class T>
void funct(vector <T> v){


}
Run Code Online (Sandbox Code Playgroud)

这个函数采用模板的向量作为它的参数,我希望做同样的事情,除了在标题中声明向量以允许向量包含任何东西.

c++ templates vector

9
推荐指数
2
解决办法
6668
查看次数