c++ - "multiple definition of..."模板函数的完全特化错误

标签 c++ templates definition


我有一个带有配置的项目:

./main.cpp  
./type_traints/TypeTraints.cpp
./type_traints/TypeTraints.hpp
./type_traints/chapter_20.hpp

./type_traints/CMakeLists.txt 文件是:

 cmake_minimum_required (VERSION 2.8)
 add_library(chapter_20 TypeTraints.cpp)

./CMakeLists.txt 如下:

cmake_minimum_required (VERSION 2.8)
project (mpl)

add_subdirectory(type_traints)
include_directories(type_traints)
link_directories(type_traints)

add_executable (mpl main.cpp)
target_link_libraries(mpl chapter_20)

文件相关部分(大部分省略)包括:
./type_traints/chapter_20.hpp

#ifndef CHAPTER_20_GUARD
#define CHAPTER_20_GUARD
#include <TypeTraints.hpp>

void chapter_20() {
  test_23();
}   
#endif //CHAPTER_20_GUARD

./type_traints/TypeTraints.hpp

#ifndef TYPE_TRAINTS_GUARD
#define TYPE_TRAINTS_GUARD
namespace details {

  template<class T> const char* class2name() {
    return "unknown";
  };

  template<> const char* class2name<int>() {
    return "int";
  };
}

template<class T>
class type_descriptor {
  friend std::ostream& operator << (std::ostream& stream, 
                                    const type_descriptor<T>& desc) {
    stream << desc.getName();
    return stream;
  }

public:
  std::string getName() const;  
};

template<class T>
std::string type_descriptor<T>::getName() const {
  return details::class2name<T>();
}

void test_23();    
#endif // TYPE_TRAINTS_GUARD

./type_traints/TypeTraints.cpp

#include<TypeTraints.hpp>

void test_23() {
  cout << type_descriptor<int>() << endl;
}

和./main.cpp

#include <chapter_20.hpp>

int main(int argc, char* argv[]) {
chapter_20();
  return 0;
}

项目编译但链接失败:

[ 50%] Building CXX object type_traints/CMakeFiles/chapter_20.dir/TypeTraints.cpp.o
Linking CXX static library libchapter_20.a
[ 50%] Built target chapter_20
[100%] Building CXX object CMakeFiles/mpl.dir/main.cpp.o
Linking CXX executable mpl
type_traints/libchapter_20.a(TypeTraints.cpp.o): In function `char const* details::cl
ass2name<int>()':                                                                   
/home/marcin/Projects/mpl/type_traints/TypeTraints.hpp:312: multiple definition of `c
har const* details::class2name<int>()'                                              
CMakeFiles/mpl.dir/main.cpp.o:/home/marcin/Projects/mpl/type_traints/TypeTraints.hpp:
312: first defined here                                                             
collect2: ld returned 1 exit status
make[2]: *** [mpl] Błąd 1
make[1]: *** [CMakeFiles/mpl.dir/all] Error 2
make: *** [all] Error 2
23:56:20@marcin-laptop ~/P

如果我从 TypeTraints.hpp 中删除 class2name 特化 ( class2name<int>()) 并仅使用通用实现,则项目链接正常。

有人知道这是为什么吗?我是否错过了配置 cmake 文件?

最佳答案

简而言之:明确(即完全)专用的模板函数不再是模板。它是一个普通函数,它遵守普通函数的一个定义规则。

换句话说,您不能在头文件中明确定义专门的函数模板。这样做会导致 ODR 违规。

只有至少依赖于一个参数的模板才是模板。 IE。 部分 特化可以在头文件中定义(因为它们仍然是模板)。 显式(即完整)特化只能在头文件中声明,但必须在实现文件中定义,就像普通函数一样。

关于c++ - "multiple definition of..."模板函数的完全特化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4494919/

相关文章:

c++ - Qt QString 十六进制值到 QByteArray

c++ - 为什么C++ 11不允许使用auto进行直接列表初始化

C++ 获取可变参数模板参数包中参数的并集?

C++ 函数重载模板值

c++ - 模板继承类派生基赋值

c - 未初始化的 C 字符串没有警告

typescript - 扩展 TypeScript 类时的方法链

c# - C#变量UserInput找不到定义

c++ - Mshtml.h教程

c++ - 在 C++ 中初始化引用不起作用,但初始化 const 引用却起作用,为什么?