我遇到了一些我无法理解的事情,也找不到适当的解决方法。我想要实现的目标看起来相对简单:我想比较一些数据。
描述的最佳方式是一行代码:
std::tuple<const char *, int, const char *, int> my_data =
std::make_tuple("hello", 13, "world", 37);
// Now I want to compare my_data againt some known value.
assert(Test::entry(my_data, "hello", 13, "world", 37));
为了示例,我使用了一个元组。我的情况是,这些数据来自消息对象,并使用operator>>
提取。但是,这与问题无关。
这是一个用于说明问题的极简主义代码。
#include <cstring>
using MyTuple = std::tuple<const char *, int, const char *, int>;
namespace Test
{
// called when we are done
bool extract(MyTuple source)
{
return true;
}
template<typename T,
typename ...Content>
bool extract(MyTuple source, T data, Content... content)
{
if (std::is_same<const char *, T>::value)
assert(0); // why ? :(
std::cout << "Generic: " << data << std::endl;
return extract(source, content...);
}
template<typename ...Content>
bool extract(MyTuple source, const char *str, Content... content)
{
std::cout << "Overloaded: " << str << std::endl;
return extract(source, content...);
}
template<typename ...Content>
bool entry(const std::tuple<const char *, int, const char *, int> &data,
Content... content)
{
return extract(data, content...);
}
};
我会在extract()
函数中正常执行比较,但为了保持示例简单,我删除了它们。
我想要实现的是适当的调度。基于这个例子,我的理解是呼叫顺序应该是:
const char *
const char *
但是,此测试程序的输出是:
Assertion failed
。 std::is_same
测试会触发assert
。我发现在泛型重载调用一次后不会调用const char *
重载。
我错过了什么?
编辑:也不是说如果我在泛型函数之前定义const char *
重载,这甚至都不会编译。
答案 0 :(得分:3)
另请注意,如果我在泛型函数之前定义
const char *
重载,则甚至无法编译。
声明应该足够了:
template <typename... Content>
bool extract(MyTuple source, const char *str, Content... content); // <- here
template <typename T, typename... Content>
bool extract(MyTuple source, T data, Content... content)
{
std::cout << "Generic: " << data << std::endl;
return extract(source, content...);
}
template <typename... Content>
bool extract(MyTuple source, const char *str, Content... content)
{
std::cout << "Overloaded: " << str << std::endl;
return extract(source, content...);
}
为什么?
在没有事先声明的特定名称查找期间,过载const char*
不可见。可以在comments below中找到一些例外情况。