1
#include <iostream>
#include <vector>
#include <memory>

class Node{
public:
    static constexpr int data_size = sizeof(int);
};

class View{
public:
    View(int size){
    }
};

class Header: public Node{
public:
    void foo(){
        std::shared_ptr<View> v = std::make_shared<View>(data_size);
    }

    void bar(){
        std::shared_ptr<View> v(new View(data_size));
    }
    View bar1(){
        return View(data_size);
    }
    void bar2(){
        View *v = new View(data_size);
    }
    int bar3(){
        return data_size;
    }
};

int main() {

    Header *h = new Header();

    // This 1 lines below will produce the error
    h->foo();

    // These 4 lines are ok
    h->bar();
    h->bar1();
    h->bar2();
    h->bar3();

    return 0;
}

调用 foo() 时会出现以下错误:

/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/everettjf/code/cpptest/cmake-build-debug --target all -- -j 8
Scanning dependencies of target cpptest
[ 50%] Building CXX object CMakeFiles/cpptest.dir/main.cpp.o
[100%] Linking CXX executable cpptest
Undefined symbols for architecture x86_64:
  "Node::data_size", referenced from:
      Header::foo() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [cpptest] Error 1
make[1]: *** [CMakeFiles/cpptest.dir/all] Error 2
make: *** [all] Error 2

当我使用 new 初始化 shared_ptr 时,没关系。但是当我使用 make_shared 时,会出现链接错误。

为什么在使用静态 constexpr 成员构造时 std::make_shared 与 new 不同?

我的环境是带有 Clion 的 macOS,CMakeList.txt 是:

cmake_minimum_required(VERSION 3.6)
project(cpptest)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(cpptest ${SOURCE_FILES})
4

1 回答 1

0

为什么新的工作..

std::shared_ptr<View> v(new View(data_size));

在上面的代码中(我的猜测是),编译器将 data_size 替换为值本身。所以它编译并运行良好。

为什么 std::make_shared<>() 失败..

std::shared_ptr<View> v = std::make_shared<View>(data_size);

std::make_shared 做了一些称为完美转发的事情。在上述情况下,它需要知道 Node::data_size 的地址。由于您尚未在任何地方定义它,因此链接器找不到符号并引发错误。

要解决此问题,请在代码中定义符号 Node::data_size。

于 2017-04-19T04:12:20.983 回答