这段代码使用 clang 编译并运行良好,但 gcc 给出编译错误:
no matching function for call to ‘unpack(tag1, A3&)’
那么它是有效的 C++ 吗?
#include <type_traits>
#include <utility>
#include <cassert>
template <class Tag, class Value>
class Pack
{
public:
Pack(const Value& value) : _value(value) {}
Value value() const { return _value; }
private:
Value _value;
};
template<class Tag, class Value>
decltype(auto) unpack(Tag, Pack<Tag, Value>& pack) {
return pack.value();
}
struct tag1 {};
struct tag2 {};
struct A3 : Pack<tag1, int>, Pack<tag2, double> {
A3(int x, double y) : Pack<tag1, int>(x), Pack<tag2, double>(y) {}
};
int main() {
A3 a3(1, 2);
assert(unpack(tag1(), a3) == 1);
assert(unpack(tag2(), a3) == 2);
}
最佳答案
Tag
位于每个函数参数的推导上下文中( Tag
和 Pack<Tag, Value> &
)。每个模板参数推导都是独立执行的,结果必须匹配。当试图推断Pack<Tag, Value>
时来自A3
,有两种可能的推导,因此类型推导失败。
最简单的修复可能是删除标签函数参数,而只需调用 unpack
使用显式模板参数 - unpack<tag1>(a3)
不比 unpack(tag1(), a3)
更详细。如果您仍然喜欢原始语法,可以编写转发器:
template<class Tag, class SomePack>
decltype(auto) unpack(Tag, SomePack& pack) { return unpack<Tag>(SomePack); }
关于c++ - 该模板函数能否正确匹配具有多个基数的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30814981/