C ++ 11可变参数模板和std :: endl [英] c++11 variadic templates and std::endl
问题描述
我尝试使用C ++ 11可变参数模板进行记录器,但不适用于 std :: endl
,因为 std: :endl
是模板函数,编译器不知道选择 std :: endl
的哪种专业。有什么方法可以强制我始终选择 std :: endl< char,std :: char_traits< char>>
?如果可能的话,我想直接使用std :: endl。
I tried to do logger using C++11 variadic templates, but it doesn't work for std::endl
, because std::endl
is template function and the compilator doesn't know what specialization of std::endl
to select. Is there any way how i can force to always select std::endl<char, std::char_traits<char>>
? If possible, i want to use directly std::endl.
编辑:看来C ++ 11当前无法使用最好的方法是使用 #define
或 vsoftco 回答。
it looks like it is not currently possible with C++11 and and best way is to use #define
or what vsoftco answered.
#include <iostream>
#include <string>
class Logger {
public:
template<typename T>
void log(T val);
template <typename T, typename ...Args>
void log(T val, Args... args);
};
// explicit specialization not working
template<>
void Logger::log(std::basic_ostream<char, std::char_traits<char>> (*modifier) (std::basic_ostream<char, std::char_traits<char>>)) {
std::cout << modifier;
}
template<typename T>
void Logger::log(T val) {
std::cout << val;
}
template<typename T, typename ...Args>
void Logger::log(T val, Args... args) {
log(val);
log(args...);
}
int main(int argc, char* argv[])
{
Logger log;
log.log("Nazdar ", "bazar ", "cau", std::endl, "kik"); // ERROR: cannot determine which instance of function template "std::endl" is intended
log.log("Nazdar ", "bazar ", "cau", std::endl<char, std::char_traits<char>>, "kik");
std::cin.get();
return 0;
}
推荐答案
我想到了这个,基本上是通过使用默认模板参数的自定义包装 my_endl
重新定义 std :: endl
的。不是最优雅的,但可以做到。当然,对于更多这样的操纵器,应该编写一个专门的包装器,但是我想,即使这样也可以通过更聪明的实现来实现。
I came up with this, basically re-defining std::endl
via a custom wrapper my_endl
taking default template parameters. Not the most elegant, but it does the job. Of course, for more such manipulators, one should write a specialized wrapper, but I guess even this can somehow be possible by a more clever implementation.
#include <iostream>
#include <string>
#include <type_traits>
class Logger {
public:
template<typename T>
void log(T val);
template <typename T, typename ...Args>
void log(T val, Args... args);
};
template<typename T>
void Logger::log(T val) {
std::cout << val;
}
template<typename T, typename ...Args>
void Logger::log(T val, Args... args) {
log(val);
log(args...);
}
template< class CharT = char, class Traits = std::char_traits<CharT> >
inline std::basic_ostream<CharT, Traits>& my_endl( std::basic_ostream<CharT, Traits>& os )
{
return std::endl(os);
}
// or, use the excellent (and better) suggestion by 0x499...,
// auto manip = std::endl<char, std::char_traits<char>>;
// log.log(..., manip)
int main(int argc, char* argv[])
{
Logger log;
// log.log("Nazdar ", "bazar ", "cau", std::endl, "kik"); // ERROR: cannot determine which instance of function template "std::endl" is intended
log.log("Nazdar ", "bazar ", "cau", my_endl<>, "kik");
std::cin.get();
return 0;
}
这篇关于C ++ 11可变参数模板和std :: endl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!