调用可变参数模板函数会在Visual Studio 2015中出现错误C2660

时间:2016-11-18 10:47:07

标签: c++ visual-studio-2015 variadic-templates

以下代码在Visual Studio 2015社区中出现C2660错误:

class Logger {
public:
    template <class T> void writeLine(const T& value) {
        if (this->filestream.is_open()) {
            filestream << object << std::endl;
        }
    }

    template <typename T> void write(const T& value) {
        if (this->filestream.is_open()) {
            filestream << value;
        }
    }

    template <typename T, typename... Targs> void write(const T& value, const Targs&... args) {
        if (this->filestream.is_open()) {
            filestream << value;
            this->write(args...);
        }
    }

    // ... singleton stuff
}

我正在调用这样的函数:

#define LOG(x) Logger::instance().write(__FILE__, " (line ", __LINE__, "): ", x, std::endl);

以下是输出日志中的错误:

encoder.cpp(51): error C2660: 'Logger::write': function does not take 6 arguments

2 个答案:

答案 0 :(得分:2)

问题是std::endl本身就是一个模板

template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );

因此可能的解决方案可能是

var.write(__FILE__, " (line ", __LINE__, "): ", 22, std::endl<char, std::char_traits<char>>);

有关此问题的更多信息here

答案 1 :(得分:1)

std::endl是一个模板,编译器没有足够的信息来选择合适的专业化。有很多方法可以支持这一点:

  • 使用std::endl<char,std::char_traits<char>>作为你的最后一个论点(哎呀)。
  • 使用'\n',这显然不等同,但可能会有效。
  • 创建一个专门的Logger::endl并发送。

可以找到后者的一个很好的例子here

无关,你应该考虑使用完美转发。让模板成员适应这一点应该是微不足道的。

template <typename T>
void write(T&& value) {
    if (this->filestream.is_open()) {
        filestream << std::forward<T>(value);
    }
}

template <typename T, typename... Args>
void write(T&& value, Args&&... args)
{
    this->write(std::forward<T>(value));
    this->write(std::forward<Args>(args)...);
}

请参阅此处:Advantages of using forward以及链接的文章The Forwarding Problem