1

我已经阅读了很多这样的问题,但我不能 100% 确定我的问题是否有所不同。我已经搜索了很多正确的答案,但大多数答案都围绕着宏守卫。我有一个从中派生的自定义字符串类,std::string后来因为我在现实世界中使用该项目,所以我不想仅仅为了扩展功能而派生 std::string。所以我将函数从 customString.h 移到了 utils_string.h 中。这是定义:

#ifndef OPS_TOOLKIT_UTILS_STRING_H
#define OPS_TOOLKIT_UTILS_STRING_H
#include <string>
#include <algorithm>
#include <vector>

namespace utils{
  namespace string{

const std::string kilikeDelimiter = "%";

void tolower(std::string& str){
    //CODE
}

bool iequals(const std::string& str1,const std::string& str2){
    //CODE
}
bool ilike(const std::string& str,const std::string& pattern){
    //CODE
}
std::string prependAndAppendILikeDelimiter(const std::string& str) {
    //CODE
}
} //namespace string
} //namespace utils

#endif

我得到了抱怨...first defined here,这是编译器的确切输出。注意:这里没有课

/tmp/ccCFVTXP.o: 在函数utils::string::tolower(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)': listings.cpp:(.text+0x0): multiple definition ofutils::string::tolower(std::basic_string, std::allocator >&)' /tmp/cczDtRdT.o:listing.cpp:(.text+0x0): 首先定义这里 /tmp/ccCFVTXP.o: 在函数utils::string::iequals(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': listings.cpp:(.text+0x55): multiple definition ofutils::string::iequals(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&)' /tmp/cczDtRdT.o: Listing.cpp:(.text+0x55): 首先定义在这里 /tmp/ccCFVTXP.o: 在函数utils::string::ilike(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': listings.cpp:(.text+0x118): multiple definition ofutils::string::ilike(std::basic_string, std::allocator > const&, std::basic_string, std: :allocator > const&)' /tmp/cczDtRdT.o:listing.cpp:(.text+0x118): 首先定义在这里 /tmp/ccCFVTXP.o: 在函数utils::string::prependAndAppendILikeDelimiter(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': listings.cpp:(.text+0x484): multiple definition ofutils::string::prependAndAppendILikeDelimiter(std::basic_string, std ::allocator > const&)' /tmp/cczDtRdT.o:listing.cpp:(.text+0x484):首先在这里定义/tmp/ccifZISK.o:在函数中utils::string::tolower(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)': match_count.cpp:(.text+0x0): multiple definition ofutils::string::tolower(std::basic_string, std::allocator >&)' /tmp/cczDtRdT.o:listing.cpp:(.text+0x0): 首先在这里定义 /tmp/ccifZISK.o: 在函数utils::string::iequals(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': match_count.cpp:(.text+0x55): multiple definition ofutils::string::iequals(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&)' /tmp/cczDtRdT.o:listing.cpp:(.text+0x55 ): 首先在这里定义 /tmp/ccifZISK.o: 在函数utils::string::ilike(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': match_count.cpp:(.text+0x118): multiple definition ofutils::string::ilike(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&)' /tmp/ cczDtRdT.o:listing.cpp:(.text+0x118): 首先定义在这里 /tmp/ccifZISK.o: 在函数utils::string::prependAndAppendILikeDelimiter(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': match_count.cpp:(.text+0x484): multiple definition ofutils::string::prependAndAppendILikeDelimiter(std::basic_string, std::allocator > const&)' /tmp /cczDtRdT.o:listing.cpp:(.text+0x484): 首先在这里定义 collect2: ld 返回 1 退出状态

我为整个混乱感到抱歉,但我不想错过任何遇到类似问题的人。

还有一件事; 它说match_count.cpp * Listing.cpp * 和Listings.cpp它只是使用 ::utils::string::function() 中定义的函数

4

2 回答 2

4

头文件不能定义代码,除非它是明确的inline。否则(因为预处理器像一个巨大的复制/粘贴机器一样工作),就好像每个执行#include.

因此,添加inline到其中的每一个中,或者将它们放在单个.cpp中,但不要放在标题中。

于 2012-07-17T01:23:38.570 回答
0

将您的函数放入这样的类中可能会更好(以下转到 .h 文件)。使用嵌套命名空间可能更常见。

#pragma once
#include <string>

namespace utils
{
    class StringUtil
    {
        public:
           static void tolower(std::string& str)
           {
               // code
           }
    };
}
于 2012-07-17T01:38:11.470 回答