我有以下代码:
#include <boost/variant.hpp>
#include <iostream>
#include <string>
boost::variant<int, double, std::string> variant;
template <typename FirstArg, typename... OtherArgs>
auto bar(const std::type_info& variant_type_info) -> decltype(typeid(FirstArg) == variant_type_info ? boost::get<FirstArg>(variant) : bar<OtherArgs...>(variant_type_info))
{
if (typeid(FirstArg) == variant_type_info)
{
return boost::get<FirstArg>(variant);
}
return bar<OtherArgs...>(variant_type_info);
}
template <typename... VariantArgs>
auto foo(const boost::variant<VariantArgs...>& variant) -> decltype(bar<VariantArgs...>(variant.type()))
{
return bar<VariantArgs...>(variant.type());
}
int main()
{
variant = 0.5;
const auto& baz = foo(variant);
std::cout << baz << '\n';
}
它给了我以下错误:
main.cpp:9:135: error: 'bar' was not declared in this scope
auto bar(const std::type_info& variant_type_info) -> decltype(typeid(FirstArg) == variant_type_info ? boost::get<FirstArg>(variant) : bar<OtherArgs...>(variant_type_info))
^
main.cpp:9:148: error: expected primary-expression before '...' token
auto bar(const std::type_info& variant_type_info) -> decltype(typeid(FirstArg) == variant_type_info ? boost::get<FirstArg>(variant) : bar<OtherArgs...>(variant_type_info))
^
main.cpp:9:148: error: expected ')' before '...' token
main.cpp:9:135: error: 'bar' was not declared in this scope
auto bar(const std::type_info& variant_type_info) -> decltype(typeid(FirstArg) == variant_type_info ? boost::get<FirstArg>(variant) : bar<OtherArgs...>(variant_type_info))
^
main.cpp:9:54: error: expected type-specifier before 'decltype'
auto bar(const std::type_info& variant_type_info) -> decltype(typeid(FirstArg) == variant_type_info ? boost::get<FirstArg>(variant) : bar<OtherArgs...>(variant_type_info))
^
main.cpp:9:54: error: expected initializer before 'decltype'
main.cpp:20:69: error: 'bar' was not declared in this scope
auto foo(const boost::variant<VariantArgs...>& variant) -> decltype(bar<VariantArgs...>(variant.type()))
^
main.cpp:20:69: error: 'bar' was not declared in this scope
main.cpp:20:84: error: expected primary-expression before '...' token
auto foo(const boost::variant<VariantArgs...>& variant) -> decltype(bar<VariantArgs...>(variant.type()))
^
main.cpp:20:84: error: expected ')' before '...' token
main.cpp:20:69: error: 'bar' was not declared in this scope
auto foo(const boost::variant<VariantArgs...>& variant) -> decltype(bar<VariantArgs...>(variant.type()))
^
main.cpp:20:69: error: 'bar' was not declared in this scope
main.cpp:20:60: error: expected type-specifier before 'decltype'
auto foo(const boost::variant<VariantArgs...>& variant) -> decltype(bar<VariantArgs...>(variant.type()))
^
main.cpp:20:60: error: expected initializer before 'decltype'
main.cpp: In function 'int main()':
main.cpp:28:34: error: 'foo' was not declared in this scope
const auto& baz = foo(variant);
Coliru示例 - http://coliru.stacked-crooked.com/a/4467c33489b08359
我看到我无法在decltype中引用相同的函数。这种情况有没有解决办法?我正在尝试编写函数来从boost :: variant对象中检索当前值。
答案 0 :(得分:3)
是的,一般情况下有解决方法。它被称为:
部分订购。要获得引用,请将方法移动到类命名空间中。
<强>然而强>
没有什么可以救你的。除非你在编译时已经知道它,否则你无法让编译器恢复参数的静态类型。这应该是显而易见的。
我的意思是,foo()
的返回类型应该是什么?它怎么可能包含所有可能的元素类型?对。这就是你开始使用变体的原因。
前进的三种方式:
静态了解类型:
const auto& baz = boost::get<double>(variant);
返回typeid:
std::type_info const& typeinfo_value = variant.type();
分支并创建单独的路径来处理所有情况。对于这种情况,Boost有static_visitor:
struct Visitor : boost::static_visitor<std::string> {
std::string operator()(std::string const&) const { return "std::string"; }
std::string operator()(int) const { return "int"; }
std::string operator()(double) const { return "double"; }
template <typename... T>
std::string operator()(boost::variant<T...> const& v) const {
return boost::apply_visitor(*this, v);
}
};
int main()
{
static const Visitor _visitor;
variant = 0.5f;
std::cout << "The actual type is " << _visitor(variant) << "\n";
}