如何触发特定函数重载调用的编译错误:禁止func接收单指针构造的std::string_view
方案1:仅禁止直接向
func传入裸指针(轻量方案) 直接新增一个删除的func重载,拦截所有const char*类型的入参即可,改动极小:
// 原有函数逻辑完全保留 void func( const std::string_view str ) { if ( str.empty( ) ) { return; } std::stringstream ss; if ( str.back( ) == '\0' ) { ss << str.data( ); } else { ss << std::string{ str }; } } // 新增一行删除重载,拦截裸指针传入 void func( const char* ) = delete;
修改后你的合法调用可以正常编译,违规调用直接报错:
func(sv):匹配std::string_view重载,正常调用func( { buffer.data( ), buffer.size( ) } ):初始化列表构造std::string_view,匹配原重载,正常调用func( buffer.data( ) ):匹配const char*删除重载,编译失败,符合要求。
注意:该方案仅拦截直接传入裸指针的场景,如果你需要拦截显式调用单参数std::string_view构造函数再传入的情况,建议使用方案2。
方案2:全局禁止单参数
std::string_view构造(严格方案) 如果你需要从类型层面彻底杜绝单参数构造的std::string_view流入业务逻辑,可以自定义安全字符串视图封装,删除单参数构造:
#include <string_view> #include <iostream> #include <sstream> #include <string> #include <array> class SafeStringView { public: // 仅允许双参数构造、以及从已构造的合法string_view转换 constexpr SafeStringView( const char* s, size_t count ) : m_view(s, count) {} constexpr SafeStringView( const std::string_view& sv ) : m_view(sv) {} // 禁止单参数裸指针构造 constexpr SafeStringView( const char* s ) = delete; // 转发所有需要用到的string_view接口 constexpr bool empty() const noexcept { return m_view.empty(); } constexpr char back() const noexcept { return m_view.back(); } constexpr const char* data() const noexcept { return m_view.data(); } constexpr size_t size() const noexcept { return m_view.size(); } constexpr operator std::string_view() const noexcept { return m_view; } private: std::string_view m_view; }; // 将func参数改为SafeStringView即可,内部逻辑无需修改 void func( const SafeStringView str ) { if ( str.empty( ) ) { return; } std::stringstream ss; if ( str.back( ) == '\0' ) { ss << str.data( ); } else { ss << std::string{ str }; } } // main函数原有逻辑无需修改 int main() { std::array<char, 20> buffer { }; std::cin.getline( buffer.data( ), 20 ); const std::string_view sv { buffer.data( ), buffer.size( ) }; func( sv ); // 允许调用 func( { buffer.data( ), buffer.size( ) } ); // 允许调用 func( buffer.data( ) ); // 禁止调用,编译报错 }
该方案可以完全拦截所有单参数构造的场景,包括显式写func(std::string_view(buffer.data()))的情况,安全性更高。
内容的提问来源于stack exchange,提问作者digito_evo
相关产品推荐
相关产品推荐

