如何修复此模板:

时间:2015-11-01 18:45:42

标签: c++ templates

template <typename IN,typename OUT,bool isVector>
OUT foo(IN x){
    if (isVector){
        return x[0];     
    } else {
        return x;
    }
}

在我错误地认为this question之后,上面的代码可以编译为例如。

foo<double,double,false>;

以及

foo<std::vector<double>,double,true>;

但是,即使其中一个if-branches永远不会被执行,也会检查它是否正确,因此上面的代码不能编译。我该如何解决?

上面的代码是简化的,但我不知道如何解决它,因为函数模板不能有部分专业化...

1 个答案:

答案 0 :(得分:4)

你可以&#34;提取&#34;你想要专门研究的模板参数,使它们成为某些结构的模板参数,并用剩余的模板参数作为静态成员函数编写函数:

template<bool IsVector = true>
struct Bar {
    template<typename In>
    static auto foo(In input) {
        return input[0];
    }
};
template<>
struct Bar<false> {
    template<typename In>
    static auto foo(In input) {
        return input;
    }
};

Live example.

显然,这会导致呼叫站点发生变化,您可以“抓住”#34;使用调用适当函数的自由函数:

template<typename In, bool IsVector>
auto real_foo(In input) {
  return Bar<IsVector>::foo(input);
}

然后,结构(Bar)通常放在&#34;帮助&#34;命名空间。

另一种可能性是使用标签和重载解析:

template<typename In>
auto foo(In input, std::true_type) {
    return input[0];
}
template<typename In>
auto foo(In input, std::false_type) {
    return input;
}
template<bool IsVector, typename In>
auto foo(In input) {
    using tag = typename conditional<IsVector, true_type, false_type>::type;
    return foo(input, tag{});
}

Live example.

这会将std::conditionalstd::true_typestd::false_type用作不同的类型,以允许重载解析来查找相应的foo函数。