首页 > 解决方案 > 如何在 C++ 中创建多类型向量

问题描述

我需要创建一个接受多种类型数据的向量。该向量将被转换为字符串并使用 SHA1 进行哈希处理。我尝试创建一个vector<boost::any>并使用创建一个字符串std::string(v.begin(), v.end()),但这导致...

/Users/yash/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/c++/v1/string:2065:22: error: no matching member function for call to 'assign'
traits_type::assign(*__p, *__first);
~~~~~~~~~~~~~^~~~~~
              /Users/yash/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/c++/v1/string:2074:5: note: in instantiation of function template specialization 'std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::__init<std::__ndk1::__wrap_iter<boost::any *> >' requested here
__init(__first, __last);
^
/Users/yash/BuildBox/GDBIAG15 android/EzNotes/app/src/main/cpp/Obfuscator.cpp:21:30: note: in instantiation of function template specialization 'std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::basic_string<std::__ndk1::__wrap_iter<boost::any *>, void>' requested here
salt = hashSaltUsingSHA1(std::string(v.begin(), v.end()));
^
/Users/yash/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/c++/v1/__string:208:10: note: candidate function not viable: no known conversion from 'boost::any' to 'const std::__ndk1::char_traits<char>::char_type' (aka 'const char') for 2nd argument
void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
^
/Users/yash/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/c++/v1/__string:227:30: note: candidate function not viable: requires 3 arguments, but 2 were provided
static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
^
1 error generated.
[2/3] Building CXX object CMakeFiles/native-lib.dir/native-lib.cpp.o
ninja: build stopped: subcommand failed.

                                 * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

编辑:对我想要做的事情有更清晰的定义。以一个字符串的形式获取多个复杂对象的原始数据,并用SHA1进行hash

标签: c++cmakeandroid-ndk

解决方案


如果您查看编译器的输出(如果您花时间的话,它们很冗长但可读),构造函数std::string需要一些 char_type 指针。您不能直接将 aboost::any转换为 char。

如果要将向量转换为字符串,则必须使用中间函数将boost::any对象内部的数据转换为 char 或字符串,然后将它们连接成一个字符串。

你可以尝试这样的事情:

#include <vector>
#include <string>
#include <iostream>
#include <boost stuff>

struct foo { };

bool is_string(boost::any *any) {
    return any_cast<std::string *>(any) != nullptr;
}

bool is_foo(boost::any *any) {
    return any_cast<foo *>(any) != nullptr;
}

std::string foo_to_string(const foo& f) {
    ....
}

std::string any_to_string(boost::any& any) {
    if (is_string(&any))
        return any_cast<std::string>(any);
    else if(is_foo(&any))
        return foo_to_string(any_cast<foo>(any));
    else
        return "";
}

int main() {
    std::vector<boost::any> objects;
    std::string result;
    
    // you can refactor that with std::accumulate
    for (const auto& object: objects) {
         result += any_to_string(foo);
    }

    std::cout << result << '\n';
    return 0;
}

我以前从未使用boost::any过,所以这可能无法开箱即用,但根据我从文档中了解到的情况,您对如何实现它有了大致的了解。

最后,您可能不需要boost::any. 如果您重新考虑您的实现,您通常可以找到更多类型安全的解决方案。但如果没有更多细节,我无法给你任何提示。


推荐阅读