是否有一个 constexpr 可以让我确定是否有特定类型的输出运算符 (<<)?



为了防止编译器将例如std::vector<T>应用于像std::cout << u这样的语句,我想做如下操作:

if constexpr (std::has_output_operator<U>) {
std::cout << u;
}

有什么办法可以做到这一点吗?

编辑(澄清(我正在开发类似printf的函数,它也可以打印POD的字符串和向量以及字符串(及其向量(。

我想将此功能扩展到任何具有输出运算符的类型。

非矢量类型的实际格式化由函数simpleFormat():完成

// simpleFormat
//  special case for single string
//
std::string simpleFormat(const std::string sFormat, const std::string t) {
size_t required = snprintf(NULL, 0, sFormat.c_str(), t.c_str());
char sTemp[required+1];
sprintf(sTemp, sFormat.c_str(), t.c_str());
return std::string(sTemp);
} 
// simpleFormat
//  catch for vectors (should not be sent to simpleFormat)
template<typename T>
std::string simpleFormat(const std::string sFormat, const std::vector<T> t) {
return "";
}
// simpleFormat
//  formatting PODs and Objects with output operator a char using     
template<typename T>
std::string simpleFormat(const std::string sFormat, const T t) {
std::string sRes = "";
if (sFormat.size() > 0) {
if (sFormat != "%O") {
size_t required = snprintf(NULL, 0, sFormat.c_str(), t);
char sTemp[required+1];
sprintf(sTemp, sFormat.c_str(), t);
sRes = std::string(sTemp);
} else {
std::stringstream ss("");
ss << t;
sRes += ss.str();    
}
} 
return sRes;
}

当我为一些应用程序编译这个时,会得到错误

In file included from AgentCounter.cpp:6: 
../utils/stdstrutilsT.h: In instantiation of ‘std::string simpleFormat(std::string, T) [with T = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; std::string = std::__cxx11::basic_string<char>]’: 
../utils/stdstrutilsT.h:195:33:   required from ‘std::string recursiveFormat(stringvec&, stringvec&, uint, T, Args ...) [with T = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; Args = {long long unsigned int}; std::string = std::__cxx11::basic_string<char>; stringvec = std::vector<std::__cxx11::basic_string<char> >; uint = unsigned int]’ 
../utils/stdstrutilsT.h:281:31:   required from ‘std::string stdsprintf(std::string, Args ...) [with Args = {__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, long long unsigned int}; std::string = std::__cxx11::basic_string<char>]’ 
../utils/stdstrutilsT.h:291:34:   required from ‘void stdprintf(std::string, Args ...) [with Args = {__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, long long unsigned int}; std::string = std::__cxx11::basic_string<char>]’ 
AgentCounter.cpp:326:22:   required from here 
../utils/stdstrutilsT.h:165:28: error: no match for ‘operator<<’ (operand types are ‘std::stringstream’ {aka ‘std::__cxx11::basic_stringstream<char>’} and ‘const __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >’) 
165 |                         ss << t; 
|                         ~~~^~~~ 

即使我有一个向量的simpleFormat()变体,编译器仍然希望将std::vector放入POD变体中。

这就是为什么我希望有constexpr,它可以让我发现传递的类型是否有输出运算符。

当然,如果还有其他可能阻止编译器将向量应用于我的非向量函数,我想了解一下。

这可以直接使用C++20required表达式来完成,该表达式检查其操作数是否有效:

if constexpr (requires { std::cout << u; })

您还可以用requires表达式定义一个命名概念,然后每次需要时都用它来代替requires表达式

相关内容

最新更新