error C2039: "ac_strlen": 不是 "std" 的成员

boost\type_index\stl_type_index.hpp(147,45): error C2039: "ac_strlen": 不是 "std" 的成员
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\numeric(23): message : 参见“std”的声明

ac_strlen这个在第三方库里是这样定义的,

#pragma once
#ifndef _AC_TCSLEN_
#define _AC_TCSLEN_

#include "adesk.h"

#if defined ASSERT
#define AcTcsLen_Assert ASSERT
#elif defined(assert)
#define AcTcsLen_Assert assert
#elif defined(_ASSERTE)
#define AcTcsLen_Assert _ASSERTE
#elif defined ATLASSERT
#define AcTcsLen_Assert ATLASSERT
#else
#define AcTcsLen_Assert(x)
#endif

#ifndef USEINTRINSTRLEN

#ifdef _tcslen
#undef _tcslen
#endif

#ifdef UNICODE
#define _tcslen ac_wcslen
#else
#define _tcslen ac_strlen
#endif

#ifdef wcslen
#undef wcslen
#endif
#define wcslen ac_wcslen
#ifdef strlen
#undef strlen
#endif
#define strlen ac_strlen

// use inline to prevent multiple definition errors.
__declspec(noinline) inline unsigned ac_wcslen(const wchar_t * s)
{
    unsigned n = 0;
    while (*s != L'\0') {
        s++;
        n++;
        AcTcsLen_Assert(n < 0x7FFFFFFE);  // 2G-1 sanity check
    }
    return n;
}

__declspec(noinline) inline unsigned ac_strlen(const char * s)
{
    unsigned n = 0;
    while (*s != '\0') {
        s++;
        n++;
        AcTcsLen_Assert(n < 0x7FFFFFFE);  //  2G-1 sanity check
    }
    return n;
}

#else

#ifndef _tcslen
#ifdef UNICODE
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif
#endif //_tcslen

#endif //USEINTRINSTRLEN

#endif //_AC_TCSLEN_

而实际上,本应该调用的是cstring里面的strlen

#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
#endif

#include <typeinfo>
#include <cstring>                                  // std::strcmp, std::strlen, std::strstr
#include <stdexcept>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/demangle.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>

#if (defined(_MSC_VER) && _MSC_VER > 1600) \
    || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
    || (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
#   define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
#else
#   include <boost/container_hash/hash.hpp>
#endif

#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
#   include <boost/type_traits/is_signed.hpp>
#   include <boost/type_traits/make_signed.hpp>
#   include <boost/type_traits/type_identity.hpp>
#endif

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

namespace boost { namespace typeindex {

/// \class stl_type_index
/// This class is a wrapper around std::type_info, that workarounds issues and provides
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
///
/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
class stl_type_index
    : public type_index_facade<
        stl_type_index, 
        #ifdef BOOST_NO_STD_TYPEINFO
            type_info
        #else
            std::type_info
        #endif
    > 
{
public:
#ifdef BOOST_NO_STD_TYPEINFO
    typedef type_info type_info_t;
#else
    typedef std::type_info type_info_t;
#endif

private:
    const type_info_t* data_;

public:
    inline stl_type_index() BOOST_NOEXCEPT
        : data_(&typeid(void))
    {}

    inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
        : data_(&data)
    {}

    inline const type_info_t&  type_info() const BOOST_NOEXCEPT;

    inline const char*  raw_name() const BOOST_NOEXCEPT;
    inline const char*  name() const BOOST_NOEXCEPT;
    inline std::string  pretty_name() const;

    inline std::size_t  hash_code() const BOOST_NOEXCEPT;
    inline bool         equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
    inline bool         before(const stl_type_index& rhs) const BOOST_NOEXCEPT;

    template <class T>
    inline static stl_type_index type_id() BOOST_NOEXCEPT;

    template <class T>
    inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT;

    template <class T>
    inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT;
};

inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
    return *data_;
}


inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
#ifdef _MSC_VER
    return data_->raw_name();
#else
    return data_->name();
#endif
}

inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
    return data_->name();
}

inline std::string stl_type_index::pretty_name() const {
    static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
    static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;

    // In case of MSVC demangle() is a no-op, and name() already returns demangled name.
    // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
    const boost::core::scoped_demangled_name demangled_name(data_->name());

    const char* begin = demangled_name.get();
    if (!begin) {
        boost::throw_exception(std::runtime_error("Type name demangling failed"));
    }

    const std::string::size_type len = std::strlen(begin);
    const char* end = begin + len;

    if (len > cvr_saver_name_len) {
        const char* b = std::strstr(begin, cvr_saver_name);
        if (b) {
            b += cvr_saver_name_len;

            // Trim leading spaces
            while (*b == ' ') {         // the string is zero terminated, we won't exceed the buffer size
                ++ b;
            }

            // Skip the closing angle bracket
            const char* e = end - 1;
            while (e > b && *e != '>') {
                -- e;
            }

            // Trim trailing spaces
            while (e > b && *(e - 1) == ' ') {
                -- e;
            }

            if (b < e) {
                // Parsing seems to have succeeded, the type name is not empty
                begin = b;
                end = e;
            }
        }
    }

    return std::string(begin, end);
}

const std::string::size_type len = std::strlen(begin);这句每次都是调那个被改过名字的库,而那个库根本不是cstring,导致找不到strlen,像这种两个第三方库冲突的情况,应该如何避免

要不试试 ... = strlen(begin);
不要std::strlen前面的std::,也不用加using namespace std;
(看不懂题目,只是给个建议)然后附可能相关的两个链接
https://learn.microsoft.com/zh-cn/cpp/error-messages/compiler-errors-1/compiler-error-c2039?view=msvc-170
https://blog.csdn.net/vv1025/article/details/131142542

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    要解决库的冲突问题,以下是一些方法:

    1. 使用命名空间:C++可以使用命名空间来避免库的冲突问题,(例如:std::strlen),这样可以确定使用的函数是哪个库中的。

    2. 使用前缀或后缀: 可以根据需要使用前缀或后缀来标识函数、变量以及类型名,以避免不同库之间的命名冲突。

    3. 在编译时链接特定的库:可以通过编译选项,指定需要链接的特定库,可以避免库之间的冲突。

    4. 重命名库中的函数名:为了避免相同名称的函数发生冲突,可以将库中的函数名重命名。这可以使用C++的命名空间,或在代码中使用typedef或宏定义等方法来实现。

    5. 修改代码:如代码中使用的是被重命名的库的函数,可以修改代码,使用正确的库中的函数名。

    以上是一些常见的避免库冲突问题的方法,选择合适的方法取决于具体情况。在使用第三方库时,还应该注意遵循库的使用规范,以防出现冲突和误用。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^