所以,假设我想使用类型擦除键入erase.
我可以为支持自然的变体创建伪方法:
pseudo_method print = [](auto&& self, auto&& os){ os << self; };
std::variant<A,B,C> var = // create a variant of type A B or C
(var->*print)(std::cout); // print it out without knowing what it is
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何将其扩展为std::any?
它不能在"原始"中完成.但是在我们分配给/构建一个std::any我们需要的类型信息时.
所以,从理论上讲,增强了any:
template<class...OperationsToTypeErase>
struct super_any {
std::any data;
// or some transformation of OperationsToTypeErase?
std::tuple<OperationsToTypeErase...> operations;
// ?? what for ctor/assign/etc?
};
Run Code Online (Sandbox Code Playgroud)
可以某种方式自动重新绑定一些代码,以便上述类型的语法可以工作.
理想情况下,它与使用变体的情况一样简洁.
template<class...Ops, class Op,
// SFINAE filter that an op matches:
std::enable_if_t< std::disjunction< std::is_same<Ops, …Run Code Online (Sandbox Code Playgroud) 例如boost::function,几乎完全移动到std::function,同样是boost::shared_ptr
但我找不到std::any?是重命名还是根本没有以新标准放置?
自从std::any引入C++ 17以来.现在可以编写这样的代码了
#include <iostream>
#include <any>
#include <string>
int main () {
const double d = 1.2;
std::any var = d;
const std::string str = "Hello World";
var = str;
}
Run Code Online (Sandbox Code Playgroud)
双被分配给变量var和比std::string被分配给它.
为什么要std::any介绍?
我认为这违反了least astonishment rule,因为我发现很难想到一种情况,这可以用来表达更清楚,我想表达的内容.
有人能给我一个很好的例子吗std::any?
假设我有一个std::any对象,该对象可能包含也可能不包含指向给定基类的某些派生类的指针B。有什么办法可以做些什么:
B *如果std::any对象包含可转换为的内容,则返回B *,或者返回似乎dynamic_cast并且std::any_cast每个都提供了此功能的一半,但是我看不到将两者结合在一起的任何方法。
我知道我可以通过多种方式来完成这项工作,包括显式枚举可转换为的每种类型B *,但这是所有DRY违规行为的源泉。
示例用例:
std::vector<std::any> setupTools(const std::string & confFile)
{
std::vector<std::any> myTools;
auto conf = parse(confFile);
for(std::string & wrenchInfo : conf["Wrenches"])
{
Wrench::setup(myTools, wrenchInfo);
}
for(std::string & hammerInfo : conf["Hammers"])
{
Hammer::setup(myTools, hammerInfo);
}
// 25 more kinds of tools
}
Factory1::init(const std::vector<std::any> & tools)
{
m_wrench = any_get<Wrench *>(tools);
m_hammer = any_get<Hammer *>(tools);
m_saw = any_get<Saw *>(tools);
}
Factory2::init(const …Run Code Online (Sandbox Code Playgroud) 标准工作草案(n4582,20.6.3,第522页)规定了以下实施建议std::any:
实现应该避免为小的包含对象使用动态分配的内存.[示例:构造的对象仅包含int.-end example]这种小对象优化只应用于is_nothrow_move_constructible_v为真的类型T.
据我所知,std::any可以通过类型擦除/虚函数和动态分配内存轻松实现.
std::any如果在销毁时没有编译时间信息,如何避免动态分配并仍然销毁这些值; 如何设计符合标准建议的解决方案?
如果有人想看到非动态部分的可能实现,我在Code Review上发布了一个:https://codereview.stackexchange.com/questions/128011/an-implementation-of-a-static-any-类型
这里的答案有点太长了.这是基于Kerrek SB对以下评论的建议.
我想std::any使用仅移动类型变量进行初始化。我发现无法移动std :: any。
在通过链接的答案使用shared_ptr解决方法之前,我测试了以下代码:
#include <utility>
#include <iostream>
#include <any>
struct move_only {
move_only() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
move_only(move_only const&) = delete;
move_only(move_only &&) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
int main() {
move_only m;
std::any a(std::move(m)); // error. copy constructor is required
}
Run Code Online (Sandbox Code Playgroud)
https://wandbox.org/permlink/h6HOSdgOnQYg4a6K
上面的代码由于move_only没有复制构造函数而输出编译错误。
我添加了复制构造函数进行测试。
#include <utility>
#include <iostream>
#include <any>
struct move_only {
move_only() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
move_only(move_only const&) { …Run Code Online (Sandbox Code Playgroud) 我在Xcode版本8.1中使用C++.我需要使用它的功能,boost::any但强烈反对将Boost的任何部分拉入我们的项目(请不要讨论它).
我看到std::any的是"合并到C++ 17" 在这里.
我想在我的Xcode 8.1项目中使用它.我已经尝试-std=c++1z在项目中使用自定义标志,但我似乎找不到它的标题.
我如何使用std::any或std::experimental::any在我的Xcode项目中?
我可以从实现中下载相应的头文件并将它们放入我的项目的源代码中吗?或者,甚至更好,实际上现在可以在我的Xcode/Clang/C++版本中使用?
我正在阅读文档std::any_cast,我觉得奇怪的是,API具有强制转换或者向被保持对象返回值或者指向它的指针.为什么不返回参考?每次使用非指针类型参数调用函数时,都需要进行复制.
我可以看到演员的指针版本可能会更多地表达意图,可能会更清楚,但为什么不返回值是这样的引用?
template<typename ValueType>
ValueType& any_cast(any* operand);
Run Code Online (Sandbox Code Playgroud)
代替
template <typename ValueType>
ValueType* any_cast(any* operand);
Run Code Online (Sandbox Code Playgroud)
此外,似乎即使您要求引用,强制转换也会删除引用并将副本返回到存储对象,请参阅http://en.cppreference.com/w/中有关函数重载1-3的返回值的说明.CPP /效用/任何/ any_cast
我想检查向量中是否存在元素。我知道下面的代码将对其进行检查。
#include <algorithm>
if ( std::find(vector.begin(), vector.end(), item) != vector.end() )
std::cout << "found";
else
std::cout << "not found";
Run Code Online (Sandbox Code Playgroud)
但是我有任何类型的向量。即std::vector<std::any>
我将元素推入这样的向量中。
std::vector<std::any> temp;
temp.emplace_back(std::string("A"));
temp.emplace_back(10);
temp.emplace_back(3.14f);
Run Code Online (Sandbox Code Playgroud)
因此,我需要查找向量中是否存在字符串“ A”。std :: find可以在这里帮助吗?
截至目前,我正在使用下面的代码来做到这一点
bool isItemPresentInAnyVector(std::vector<std::any> items, std::any item)
{
for (const auto& it : items)
{
if (it.type() == typeid(std::string) && item.type() == typeid(std::string))
{
std::string strVecItem = std::any_cast<std::string>(it);
std::string strItem = std::any_cast<std::string>(item);
if (strVecItem.compare(strItem) == 0)
return true;
}
else if (it.type() == typeid(int) && item.type() == typeid(int))
{
int …Run Code Online (Sandbox Code Playgroud) 我正在尝试一些事情并提出以下问题:是否有可能在 a 中存储对值的引用std::any?
我尝试了以下方法:
#include <any>
#include <iostream>
#include <functional>
auto func_by_pointer(std::any obj)
{
*std::any_cast<int *>(obj) += 2;
}
auto modify_by_pointer(int &a)
{
func_by_pointer(std::make_any<int *>(&a));
}
auto func_by_reference_wrapper(std::any obj)
{
std::any_cast<std::reference_wrapper<int>>(obj).get() -= 2;
}
auto modify_by_reference_wrapper(int &a)
{
func_by_reference_wrapper(std::make_any<std::reference_wrapper<int>>(a));
}
auto func_by_reference(std::any obj)
{
std::any_cast<int &>(obj) *= 2;
}
auto modify_by_reference(int &a)
{
func_by_reference(std::make_any<int &>(a));
}
int main()
{
auto value = 3;
std::cout << value << '\n';
modify_by_pointer(value);
std::cout << value << '\n';
modify_by_reference_wrapper(value);
std::cout << value …Run Code Online (Sandbox Code Playgroud)