c ++ 11可变参数模板和std :: endl

Kra*_*rab 6 c++ c++11

我尝试使用C++ 11可变参数模板做记录器,但它不起作用std::endl,因为std::endl是模板功能,并且编译器不知道std::endl要选择什么专业.有什么方法可以强制总是选择std::endl<char, std::char_traits<char>>?如果可能的话,我想直接使用std :: endl.

编辑:它看起来目前不可能与C++ 11和最好的方法是使用#definevsoftco回答.

#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;
}
Run Code Online (Sandbox Code Playgroud)

M.M*_*M.M 5

实现相同目标的更简单选择:

// global or class member
enum MyEndl { my_endl };

// class member function
void log(MyEndl x) { std::cout << std::endl; }
Run Code Online (Sandbox Code Playgroud)

用法:

log.log("Nazdar ", "bazar ", "cau", my_endl, "kik");
Run Code Online (Sandbox Code Playgroud)


vso*_*tco 3

std::endl我想出了这个,基本上是通过采用默认模板参数的自定义包装器重新定义my_endl。不是最优雅的,但它可以完成工作。当然,对于更多这样的操纵器,应该编写一个专门的包装器,但我想即使这也可以通过更聪明的实现来实现。

#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;
}
Run Code Online (Sandbox Code Playgroud)