在我看来,您正在使用函数模板专业化。需要为每个调用提供不同的实现符合要求。但是有一个警告,那就是特化可能不会改变被特化的主模板的签名,只会改变实现。这意味着我们不能做例如
template<int t> int test(); // Primary
template<> int test<0>() { return 8; } // OK, signature matches
template<> float test<1>() { return 8.8; } // ERROR
但我们还没有被烤熟。专业化的签名必须与主要针对特定参数获得的签名相匹配。因此,如果我们使返回类型依赖模板参数,并解析为正确的类型,我们就可以很好地定义我们的特化。
template<int t> auto test() -> /* Magic involving t that resolves to int, float, string */;
template<> int test<0>() { return 8; }
template<> float test<1>() { return 8.8; }
template<> std::string test<2>() { return "8.9"; }
这样的东西存在吗?是的,你暗示过。我们可以使用std::tuple。它有一个std::tuple_element 实用程序,可以将整数映射到类型序列之一(元组的元素)。借助一个小助手,我们可以按照您希望的方式构建代码:
using types = std::tuple<int, float, std::string>;
template<int t> auto test() -> std::tuple_element_t<t, types>;
template<> int test<0>() { return 8; }
template<> float test<1>() { return 8.8; }
template<> std::string test<2>() { return "8.9"; }
现在每个特化都与主要的签名相匹配。所以我们得到了编译器的批准。
See it live