Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么链接器抱怨此模板中存在多个定义?_C++_Templates_Template Specialization - Fatal编程技术网

C++ 为什么链接器抱怨此模板中存在多个定义?

C++ 为什么链接器抱怨此模板中存在多个定义?,c++,templates,template-specialization,C++,Templates,Template Specialization,当包含在至少两个翻译单元(cpp文件)中时,这段代码会触发链接器的愤怒: \ifndef最大水电站 #定义最大水电站 模板 T最大值(常数T&a、常数T&b) { 返回a>b?a:b; } /*哑专业化*/ 模板 最大整数(常数整数和a、常数整数和b) { 返回a>b?a:b; } #endif//最大水电站 但编译和链接与一个翻译单元很好。如果我删除专门化,它在所有情况下都可以正常工作。以下是链接器消息: g++ -o test.exe Sources\test.o Sources\othe

当包含在至少两个翻译单元(cpp文件)中时,这段代码会触发链接器的愤怒:

\ifndef最大水电站
#定义最大水电站
模板
T最大值(常数T&a、常数T&b)
{
返回a>b?a:b;
}
/*哑专业化*/
模板
最大整数(常数整数和a、常数整数和b)
{
返回a>b?a:b;
}
#endif//最大水电站
但编译和链接与一个翻译单元很好。如果我删除专门化,它在所有情况下都可以正常工作。以下是链接器消息:

g++ -o test.exe Sources\test.o Sources\other_test.o
Sources\other_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)'
Sources\test.o:test.cpp:(.text+0x14): first defined here
g++-o test.exe Sources\test.o Sources\other_test.o
Sources\other_test.o:other_test.cpp:(.text+0x0):“int max(int const&,int const&)”的多重定义
Sources\test.o:test.cpp:(.text+0x14):首先在这里定义
不允许多次实例化模板吗?如何解释此错误以及如何修复它


谢谢你的建议

这是因为完整的显式模板专门化只能定义一次-虽然链接器允许隐式专门化定义多次,但它不允许显式专门化,它只是将其视为普通函数。
要修复此错误,请在源文件中放置所有专门化,如:

// header

// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
T maximum(const T & a, const T & b)
{
    return a > b ? a : b ;
}

// must be in header file to make sure the compiler doesn't make an implicit 
// specialization
template<> int maximum(const int & a, const int & b);

// source

// must be in source file so the linker won't see it twice
template<>
int maximum(const int & a, const int & b)
{
    return a > b ? a : b ;
}
//头
//必须在头文件中,因为编译器需要专门化它
//不同的翻译单位
模板
T最大值(常数T&a、常数T&b)
{
返回a>b?a:b;
}
//必须位于头文件中,以确保编译器不会生成隐式
//专业化
模板整数最大值(常数整数和a、常数整数和b);
//来源
//必须位于源文件中,以便链接器不会看到它两次
模板
最大整数(常数整数和a、常数整数和b)
{
返回a>b?a:b;
}

内联声明函数

// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
inline T maximum(const T & a, const T & b)
{
    return a > b ? a : b ;
}

/* dumb specialization */
template<>
inline int maximum(const int & a, const int & b)
{
    return a > b ? a : b ;
}
//必须在头文件中,因为编译器需要专门化它
//不同的翻译单位
模板
内联T最大值(常数T&a、常数T&b)
{
返回a>b?a:b;
}
/*哑专业化*/
模板
内联整数最大值(常数整数和a、常数整数和b)
{
返回a>b?a:b;
}

我非常感激!我正要问你如何重写头文件!你可能应该从你的函数中返回一个引用,这只是我在一个更复杂的代码中跟踪错误的一个例子。我认为这个例子在没有任何参考资料的情况下会更加清晰:)非常感谢!我想如果我们能把你的答案和丹尼的答案结合起来,我们就能得到一个完整而准确的答案。
// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
inline T maximum(const T & a, const T & b)
{
    return a > b ? a : b ;
}

/* dumb specialization */
template<>
inline int maximum(const int & a, const int & b)
{
    return a > b ? a : b ;
}