相关疑难解决方法(0)

未定义的对静态constexpr char []的引用

我想static const char在班上有一个数组.海湾合作委员会抱怨并告诉我应该使用constexpr,虽然现在它告诉我这是一个未定义的参考.如果我使数组成为非成员,那么它将编译.到底是怎么回事?

// .hpp
struct foo {
  void bar();
  static constexpr char baz[] = "quz";
};

// .cpp
void foo::bar() {
  std::string str(baz); // undefined reference to baz
}
Run Code Online (Sandbox Code Playgroud)

c++ static-members constexpr c++11

168
推荐指数
5
解决办法
4万
查看次数

了解静态constexpr成员变量

我对static constexprC++ 11中的成员变量有一些疑惑.

在first.hpp中

template<typename T>
struct cond_I
{ static constexpr T value = 0; }; 


// specialization 
template<typename T>
struct cond_I< std::complex<T> >
{ static constexpr std::complex<T> value = {0,1}; }; 
Run Code Online (Sandbox Code Playgroud)

在main()函数中

cout << cond_I<double>::value << endl;            // this works fine
cout << cond_I< complex<double> >::value << endl; // linker error
Run Code Online (Sandbox Code Playgroud)

但是,如果我添加以下行,first.hpp一切正常.

template<typename T1> 
constexpr std::complex<T1> cond_I< std::complex<T1> >::value;
Run Code Online (Sandbox Code Playgroud)

我理解的(我可能是错的)是,cond_I< std::complex<double> >::value需要一个定义,但在前一种情况下它只有声明.但那又怎么样cond_I<double>::value?为什么它不需要定义?

再次,在另一个头文件中second.hpp,我有:

在second.hpp中

// empty struct
template<typename T> …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

18
推荐指数
1
解决办法
1万
查看次数

静态constexpr odr-used or not?

为什么下面的工作原理gcc却没有clang,(现场观看):

constexpr int giveMeValue() { return 42; }

struct TryMe {
  static constexpr int arr[1] = {
      giveMeValue()
  };  
};

int main() {
    int val = TryMe::arr[0];
    return val;
}
Run Code Online (Sandbox Code Playgroud)

我得到一个未解决的外部符号与clang.

是TryMe::arr[0]一个对象?如果是的话,它是否经常使用?

c++ one-definition-rule constexpr c++11

9
推荐指数
1
解决办法
1758
查看次数

如何防止优化远离静态const

是否可以使用编译器命令行选项来防止静态const成员优化?

这是一个例子:

template <unsigned v1>
struct TRAITS {
    static const unsigned val1 = v1;
};

template < class TRAITS >
struct foo {
    static const unsigned x1 = TRAITS::val1;
};

int main () {
    foo<TRAITS<1>> f1;
    // SET BREAKPOINT HERE
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译:

g++ -g -O0 optimize_out.cpp
Run Code Online (Sandbox Code Playgroud)

GDB:

gdb a.out
(gdb) break optimize_out.cpp:13
(gdb) r
(gdb) p f1 
$1 = {static x1 = <optimized out>}
Run Code Online (Sandbox Code Playgroud)

这段代码的具体内容是类是模板.可能在C++标准中有一些东西迫使编译器优化字段,即使使用-O0?当我不使用模板时,值不会被优化:

struct foo {
    static const unsigned x1 = 1;
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我可以在调试器中看到x1

c++ g++

8
推荐指数
1
解决办法
448
查看次数

"潜在评估"是否与C++ 03中的"odr-used"相同?

举个例子:

#include <iostream>

class A
{
public:
    static const int numberOfWheels = 4;
};

// const int A::numberOfWheels;

int main()
{
    std::cout << A::numberOfWheels << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

难道是正式未定义行为(UB),因为A::numberOfWheels是使用没有它的定义是什么?(另见这里).正如C++ 03所述:

如果在程序中使用该成员,并且名称空间范围定义不包含初始化程序,则该成员仍应在名称空间作用域中定义.

我发现在C++ 03 中使用的定义相当混乱,因为它指向可能被评估的表达式:

如果对象或非重载函数的名称出现在可能已评估的表达式中,则使用该函数.

从我的猜测来看,它排除了以下表达式:

sizeof(A::numberOfWheels) ;
typeid(A::numberOfWheels).name() ;
Run Code Online (Sandbox Code Playgroud)

但不一定是<<像上面那样重载运算符的表达式.

c++ language-lawyer c++03

6
推荐指数
1
解决办法
377
查看次数