0

我已经仔细阅读了可变参数模板的链接器错误,但它似乎并没有解决我的问题。

我有 3 个文件,detail.h,detail.cppmain.cpp.

其中detail.h只有一行声明了可变参数函数allSame

//detail.h
bool allSame(unsigned long...);

detail.cpp中,提供了函数的实现。

//detail.cpp
#include "detail.h"
bool allSame() { return true; }
bool allSame(unsigned long first) { return true; }
bool allSame(unsigned long first, unsigned long second) { 
    return first == second; 
}
bool allSame(unsigned long first, unsigned long second, unsigned long others...) {
    if (first == second)
        return allSame(first, others);
    else 
        return false;
}

可以很容易地推断,allSame如果其可变参数都相同,则该函数的目的是返回。

//main.cpp
#include "detail.h"
#include <iostream>

int main () {
    if (allSame(2, 2, 2, 2)) 
        std::cout << "All same. " << std::endl;
}

在编译和链接上述三个文件(使用 command g++ detail.cpp main.cpp)时,我收到了这个链接器错误

/disk1/tmp/ccTrBHWU.o: In function `main':
main.cpp:(.text+0x1e): undefined reference to `allSame(unsigned long, ...)'
collect2: error: ld returned 1 exit status

确实,我没有提供带有特定签名的重载allSame(unsigned long, ...);但是我确实为函数定义提供了 0、1、2、2+(any) 个参数。也许编译器在函数调用时扩展参数包的方式比我想象的更微妙?

[旁注]如果我将内容移动detail.cppdetail.h然后程序编译并按预期运行。

4

2 回答 2

1

您正在声明一个可变参数函数,但您定义了非可变参数重载。编译器发出针对可变参数形式的代码(因为这是可见的声明),但链接器无法找到匹配的定义。

要么为非可变参数形式编写声明,要么编写(定义)一个实际的可变参数函数,或者更好地编写一个可变参数模板(其定义应放在头文件中)。

于 2018-07-25T16:32:07.597 回答
1

在 c++ 中,我们可以简单地编写:

template < typename S, typename ... T>
constexpr bool allSame( S first, T ... t ) 
{   
    return ((first == t) && ...) ;
}   

int main()
{   
    std::cout << allSame( 5,4,3 ) << std::endl;
    std::cout << allSame( 10,10,10,10 ) << std::endl;
}   

因此不再需要使用带有可变参数的可变参数函数或使用递归模板。

但是如果你喜欢递归模板,你可以这样做:

template < typename S, typename ... T>  
constexpr bool allSame( S , T ... );

template <typename FIRST>
constexpr bool allSame( FIRST first ) { return true; }

template < typename FIRST, typename SECOND, typename ... REST>
constexpr bool allSame( FIRST first, SECOND second, REST ... rest )
{   
    if ( first != second ) return false;
    return allSame( second , rest... );
}   

int main()
{   
    std::cout << allSame( 5,4,3 ) << std::endl;
    std::cout << allSame( 10,10,10,10 ) << std::endl;
} 

不应使用使用旧 c 样式可变参数的函数。我不知道您想看到什么,因为您的代码中没有使用模板或可变参数!

于 2018-07-25T16:34:44.187 回答