虚拟调试 class 卡在 std::endl 过载
Dummy debug class stuck on std::endl overload
我想我会做一个快速而肮脏的 __DEBUG
启用跟踪,像这样:
#ifdef __DEBUG
# define dbg std::cout
# define err std::cerr
#else
#include <iostream>
class dummy_cout
{
private:
public:
dummy_cout & operator << ( auto &obj )
{ return *this; }
dummy_cout & operator << ( std::result_of< decltype( &std::endl ) >::type &obj )
{ return *this; }
};
# define dbg dummy_cout()
# define err dummy_cout()
#endif
int main( int argc, char *argv[] )
{
dbg << "Bla, bla. bla..." << std::endl;
}
但它给了我:
cond_dbg.cpp:16:66: error: decltype cannot resolve address of overloaded function
dummy_cout & operator << ( std::result_of< decltype( &std::endl ) >::type &obj )
我也尝试了 decltype
、result_of
、ostream
等六种变体,但我仍然没有更进一步。
应该很简单。如果我编译定义 __DEBUG
的代码,我将得到 cout
和 cerr
。如果我进行正常编译,我会得到我的 dummy_cout
,它什么都不做,只是允许我的代码在没有更改和很少混乱的情况下进行编译。
任何帮助将不胜感激。
你不能写 decltype(&std::endl)
因为 std::endl
不是一个函数,它是一个 函数模板:
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );
因此,它没有类型,所以要求它没有意义。此外,即使它确实有一个类型,随后的 result_of
包装也没有任何意义。
std::cout << std::endl
起作用的原因是有一个 overload 接受特定类型的函数指针:
basic_ostream& operator<<(
std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&) );
此运算符不是函数模板(它是 basic_ostream
的成员函数,后者是 class 模板),因此此处的重载决策会触发 [=21] 的特化实例化=].
要让它工作,你应该做同样的事情:
dummy_cout& operator<<( std::ostream&(*p)(std::ostream&) );
或者选择一些合适的 CharT
和 Traits
作为你的虚拟类型:
dummy_cout& operator<<( std::basic_ostream<C,T>&(*p)(std::basic_ostream<C,T>& ) );
请注意。此声明在任何 C++ 标准中都是错误格式的:
dummy_cout& operator<<(auto& obj);
简洁的函数模板语法是Concepts TS的一个特点,它仍然是一个TS。除非你使用 -fconcepts
,否则你需要写:
template <class T>
dummy_cout& operator<<(T& obj);
我想我会做一个快速而肮脏的 __DEBUG
启用跟踪,像这样:
#ifdef __DEBUG
# define dbg std::cout
# define err std::cerr
#else
#include <iostream>
class dummy_cout
{
private:
public:
dummy_cout & operator << ( auto &obj )
{ return *this; }
dummy_cout & operator << ( std::result_of< decltype( &std::endl ) >::type &obj )
{ return *this; }
};
# define dbg dummy_cout()
# define err dummy_cout()
#endif
int main( int argc, char *argv[] )
{
dbg << "Bla, bla. bla..." << std::endl;
}
但它给了我:
cond_dbg.cpp:16:66: error: decltype cannot resolve address of overloaded function
dummy_cout & operator << ( std::result_of< decltype( &std::endl ) >::type &obj )
我也尝试了 decltype
、result_of
、ostream
等六种变体,但我仍然没有更进一步。
应该很简单。如果我编译定义 __DEBUG
的代码,我将得到 cout
和 cerr
。如果我进行正常编译,我会得到我的 dummy_cout
,它什么都不做,只是允许我的代码在没有更改和很少混乱的情况下进行编译。
任何帮助将不胜感激。
你不能写 decltype(&std::endl)
因为 std::endl
不是一个函数,它是一个 函数模板:
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );
因此,它没有类型,所以要求它没有意义。此外,即使它确实有一个类型,随后的 result_of
包装也没有任何意义。
std::cout << std::endl
起作用的原因是有一个 overload 接受特定类型的函数指针:
basic_ostream& operator<<(
std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&) );
此运算符不是函数模板(它是 basic_ostream
的成员函数,后者是 class 模板),因此此处的重载决策会触发 [=21] 的特化实例化=].
要让它工作,你应该做同样的事情:
dummy_cout& operator<<( std::ostream&(*p)(std::ostream&) );
或者选择一些合适的 CharT
和 Traits
作为你的虚拟类型:
dummy_cout& operator<<( std::basic_ostream<C,T>&(*p)(std::basic_ostream<C,T>& ) );
请注意。此声明在任何 C++ 标准中都是错误格式的:
dummy_cout& operator<<(auto& obj);
简洁的函数模板语法是Concepts TS的一个特点,它仍然是一个TS。除非你使用 -fconcepts
,否则你需要写:
template <class T>
dummy_cout& operator<<(T& obj);