boost::static_visitor 未能专门化具有多种不同可能类型的函数模板
boost::static_visitor failed to specialise function template with multiple different possible types
我正在尝试创建一个访问者函数,它将我的 boost::variant
的值加在一起。我在类型不同的情况下使用模板,例如 int + float
typedef boost::variant<int, float> Values;
struct Add : public boost::static_visitor<Values> {
template <typename T, typename U>
auto operator() (T a, U b) const -> decltype(a + b) {
return a + b;
}
}
这可以编译并且工作正常
std::cout << boost::apply_visitor(Add{}, (Values)2, (Values)5) << std::endl;
std::cout << boost::apply_visitor(Add{}, (Values)2, (Values)5.123) << std::endl;
7
7.123
但是我还想在 Values
变体中添加一个 std::string
,这样我也可以将字符串加在一起。例如,我知道不可能执行 string + int
,但在尝试通过访问者 运行 之前,我会确保 Values
都是字符串。
typedef boost::variant<int, float, std::string> Values;
std::cout << boost::apply_visitor(Add{}, (Values)"hello", (Values)"world") << std::endl;
但是程序没有编译,给我错误:
Failed to specialize function template 'unknown-type Add::operator ()(T,U) const'
我知道 std::string
是一个对象而不是类型,因此这种错误是有道理的,所以我试图通过在 Add
当输入都是字符串时的结构:
auto operator() (std::string a, std::string b) const {
return a + b;
}
但是我得到了错误
std::basic_string,std::allocator> Add::operator ()(std::string,std::string) const': cannot convert argument 1 from 'T' to 'std::string'
看起来它仍在尝试通过模板化访问者 运行 字符串参数。我哪里错了?有没有更好的方法来实现我正在尝试做的事情?抱歉,如果答案很明显,我对 C++、boost 和模板还是很陌生。
apply_visitor
应该处理所有组合(即使你是无效组合)。
你可能会:
using Values = boost::variant<int, float, std::string>;
// Helper for overload priority
struct low_priority {};
struct high_priority : low_priority{};
struct Add : public boost::static_visitor<Values> {
template <typename T, typename U>
auto operator() (high_priority, T a, U b) const -> decltype(Values(a + b)) {
return a + b;
}
template <typename T, typename U>
Values operator() (low_priority, T, U) const {
// string + int, float + string, ...
throw std::runtime_error("Incompatible arguments");
}
template <typename T, typename U>
Values operator() (T a, U b) const {
return (*this)(high_priority{}, a, b);
}
};
我正在尝试创建一个访问者函数,它将我的 boost::variant
的值加在一起。我在类型不同的情况下使用模板,例如 int + float
typedef boost::variant<int, float> Values;
struct Add : public boost::static_visitor<Values> {
template <typename T, typename U>
auto operator() (T a, U b) const -> decltype(a + b) {
return a + b;
}
}
这可以编译并且工作正常
std::cout << boost::apply_visitor(Add{}, (Values)2, (Values)5) << std::endl;
std::cout << boost::apply_visitor(Add{}, (Values)2, (Values)5.123) << std::endl;
7
7.123
但是我还想在 Values
变体中添加一个 std::string
,这样我也可以将字符串加在一起。例如,我知道不可能执行 string + int
,但在尝试通过访问者 运行 之前,我会确保 Values
都是字符串。
typedef boost::variant<int, float, std::string> Values;
std::cout << boost::apply_visitor(Add{}, (Values)"hello", (Values)"world") << std::endl;
但是程序没有编译,给我错误:
Failed to specialize function template 'unknown-type Add::operator ()(T,U) const'
我知道 std::string
是一个对象而不是类型,因此这种错误是有道理的,所以我试图通过在 Add
当输入都是字符串时的结构:
auto operator() (std::string a, std::string b) const {
return a + b;
}
但是我得到了错误
std::basic_string,std::allocator> Add::operator ()(std::string,std::string) const': cannot convert argument 1 from 'T' to 'std::string'
看起来它仍在尝试通过模板化访问者 运行 字符串参数。我哪里错了?有没有更好的方法来实现我正在尝试做的事情?抱歉,如果答案很明显,我对 C++、boost 和模板还是很陌生。
apply_visitor
应该处理所有组合(即使你是无效组合)。
你可能会:
using Values = boost::variant<int, float, std::string>;
// Helper for overload priority
struct low_priority {};
struct high_priority : low_priority{};
struct Add : public boost::static_visitor<Values> {
template <typename T, typename U>
auto operator() (high_priority, T a, U b) const -> decltype(Values(a + b)) {
return a + b;
}
template <typename T, typename U>
Values operator() (low_priority, T, U) const {
// string + int, float + string, ...
throw std::runtime_error("Incompatible arguments");
}
template <typename T, typename U>
Values operator() (T a, U b) const {
return (*this)(high_priority{}, a, b);
}
};