如何在C++可变参数函数中获取第一个特定类型的参数?
解决可变参数模板
getFirst函数的类型转换错误 你的问题核心在于运行时if判断无法阻止编译器对所有分支做类型检查——哪怕arg类型和T不匹配,编译器仍会尝试编译return arg;语句,进而触发类型转换错误。
只需要把普通if替换为编译时的constexpr if(C++17及以上版本支持),就能让编译器仅处理符合条件的分支,这就是你说的「一处小修改」:
#include <stdexcept> #include <string> #include <type_traits> // 自定义异常示例 class someCustomException : public std::runtime_error { public: using std::runtime_error::runtime_error; }; // 无匹配类型时的 fallback template<typename T> auto getFirst() -> T { throw someCustomException("Argument list not including the specific type."); } template<typename T, typename Arg, typename... Args> auto getFirst(Arg arg, Args... args) -> T { // 编译时分支判断,仅编译符合条件的代码路径 if constexpr (std::is_same_v<T, Arg>) { return arg; } else { return getFirst<T>(args...); } } // 测试调用 int main() { std::string thisIsATest = "This is a test"; std::string thisIsAnOtherString = "This is an other string"; int intValue = 5; double doubleValue = 28.563; auto result = getFirst<std::string>(5, 1.2567, intValue, true, thisIsATest, doubleValue, false, 945.621, thisIsAnOtherString); // result 会正确获取到 thisIsATest }
修改说明:
- 用
constexpr if替代普通if:编译时直接判断类型匹配情况,不匹配的分支不会被编译,彻底避免无关的类型转换检查 - 使用
std::is_same_v<T, Arg>简化代码:等价于std::is_same<T, Arg>::value,是C++17引入的便捷写法 - 调整判断逻辑顺序:先处理类型匹配的情况,代码结构更清晰
如果需要兼容C++17之前的版本,可以通过SFINAE(重载决议)实现,但constexpr if是最简洁直观的解决方案。
内容的提问来源于stack exchange,提问作者mirrowwinger
相关产品推荐
相关产品推荐

