Автоматический конструктор в явно созданном шаблоне класса

у меня естьtemplate<bool VAR> struct Obj шаблон объявлен в заголовочном файле (obj.h) с явным автоматическим конструктором перемещения (= default).

// obj.h
#pragma once
#include <vector>

template<bool VAR>
struct Obj {
  std::vector<int> member;
  Obj(int m): member(m) { }
  Obj(Obj&&) = default;
  int member_fun() const;
};

extern template struct Obj<false>;
extern template struct Obj<true>;

Функция-член шаблона определена в другом файле (obj.cpp) с явной реализацией шаблона:

// obj.cpp
#include "obj.h"

template<bool VAR>
int Obj<VAR>::member_fun() const {
  return 42;
}

template struct Obj<false>;
template struct Obj<true>;

Этот шаблон затем используется из основного файла (main.cpp):

// main.cpp
#include <utility>
#include "obj.h"

int main() {
  Obj<true> o1(20);
  Obj<true> o2(std::move(o1));
  return o2.member_fun();
}

.cppЗатем они компилируются и связываются вместе со следующимиMakefile:

#CXX=clang++
CXX=g++
CXXFLAGS=-Wall -Wextra -std=c++14

a.out: obj.o main.o
    $(CXX) $(CXXFLAGS) $^ -o a.out

obj.o: obj.cpp obj.h
    $(CXX) $(CXXFLAGS) -c 
#CXX=clang++
CXX=g++
CXXFLAGS=-Wall -Wextra -std=c++14

a.out: obj.o main.o
    $(CXX) $(CXXFLAGS) $^ -o a.out

obj.o: obj.cpp obj.h
    $(CXX) $(CXXFLAGS) -c $< -o $@
main.o: main.cpp obj.h
    $(CXX) $(CXXFLAGS) -c $< -o $@
lt; -o $@ main.o: main.cpp obj.h $(CXX) $(CXXFLAGS) -c
#CXX=clang++
CXX=g++
CXXFLAGS=-Wall -Wextra -std=c++14

a.out: obj.o main.o
    $(CXX) $(CXXFLAGS) $^ -o a.out

obj.o: obj.cpp obj.h
    $(CXX) $(CXXFLAGS) -c $< -o $@
main.o: main.cpp obj.h
    $(CXX) $(CXXFLAGS) -c $< -o $@
lt; -o $@

Тем не менее, я получаю ошибку компоновщика:undefined reference to 'Obj<true>::Obj(Obj<true>&&)' - компилятор явно не создавал экземпляр конструктора.

Obj<true>::member_fun() определяется, и программа действительно связывает успешно, если я удаляю ссылку на конструктор перемещения изmain.cpp.Если я удалюextern template из шапки программа компилируется.Если я используюint вместоstd::vector<int> для типаmemberПрограмма также компилируется.cppreference.com утверждает, что «компилятор объявит конструктор перемещения как неявныйв соответствии публичный член своего класса ". Однако, определенный вручнуюObj(int) Конструктор также встроен, но он правильно создан.

(Я получил эту ошибку с Clang в проекте, который прекрасно скомпилирован с GCC, поэтому я подумал, что это ошибка Clang. Однако, когда я уменьшил проблему до этого простого случая, и GCC 5.4.0, и Clang 3.8.0 выдают одинаковое Результаты.)

Ответы на вопрос(3)

Ваш ответ на вопрос