const#u cast似乎被C+忽略+;模板? 我写了一个简单的日志记录类,它支持在Windows上使用VisualStudio C++中的可变模板。我创建了一个通用的Log函数模板,其中包含许多专门化,以满足可能输入的常见组合 #pragma once #include <Windows.h> #include <locale> #include <codecvt> #include <string> #include <sstream> #include <utility> using namespace std; inline static string to_utf8(const wstring& s) { wstring_convert<codecvt_utf8_utf16<wchar_t>> utf16conv; return utf16conv.to_bytes(s); } class Logger { public: HANDLE file_handle; wchar_t file_path[MAX_PATH + 1]; inline Logger(HANDLE handle) : file_handle(handle), file_path{} { } inline Logger(const string& path) : Logger(path.c_str()) { } inline Logger(const wstring& path) : Logger(path.c_str()) { } inline Logger(const char* path) : file_handle(NULL) { wstring_convert<codecvt_utf8_utf16<wchar_t>> converter; wcscpy_s(file_path, MAX_PATH + 1, converter.from_bytes(path).c_str()); } inline Logger(const wchar_t* path) : file_handle(NULL) { wcscpy_s(file_path, MAX_PATH + 1, path); } private: inline void VerifyInitialize() { if ((file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) && file_path[0] != '\0') { file_handle = CreateFileW(file_path, FILE_GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(file_path, 0, NULL, FILE_END); } } public: inline void Log() { } template<typename ...Rest> inline void Log(const char* first, Rest... params) { VerifyInitialize(); if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) return; DWORD written; WriteFile(file_handle, first, static_cast<DWORD>(strlen(first)), &written, NULL); Log(params...); } template<typename ...Rest> inline void Log(const char first, Rest... params) { char str[2]; str[0] = first; str[1] = '\0'; Log(str, params...); } template<typename ...Rest> inline void Log(const string* first, Rest... params) { VerifyInitialize(); if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) return; DWORD written; WriteFile(file_handle, first->c_str(), static_cast<DWORD>(first->size()), &written, NULL); Log(params...); } template<typename ...Rest> inline void Log(const string& first, Rest... params) { Log(&first, params...); } template<typename ...Rest> inline void Log(const wstring* first, Rest... params) { Log(*first, params...); } template<typename ...Rest> inline void Log(const wstring& first, Rest... params) { Log(to_utf8(first), params...); } template<typename ...Rest> inline void Log(const wchar_t* first, Rest... params) { Log(wstring(first), params...); } template<typename ...Rest> inline void Log(const wchar_t first, Rest... params) { wchar_t str[2]; str[0] = first; str[1] = '\0'; Log(str, params...); } template<typename First, typename ...Rest> inline void Log(First first, Rest... params) { printf("%s\n", typeid(First).name()); if (is_const<First>::value) { stringstream stream; stream << first; Log(stream.str(), params...); } else Log(const_cast<const First>(first), params...); } inline ~Logger() { if (!(file_handle == NULL || file_handle == INVALID_HANDLE_VALUE)) { CloseHandle(file_handle); file_handle = NULL; } } };

const#u cast似乎被C+忽略+;模板? 我写了一个简单的日志记录类,它支持在Windows上使用VisualStudio C++中的可变模板。我创建了一个通用的Log函数模板,其中包含许多专门化,以满足可能输入的常见组合 #pragma once #include <Windows.h> #include <locale> #include <codecvt> #include <string> #include <sstream> #include <utility> using namespace std; inline static string to_utf8(const wstring& s) { wstring_convert<codecvt_utf8_utf16<wchar_t>> utf16conv; return utf16conv.to_bytes(s); } class Logger { public: HANDLE file_handle; wchar_t file_path[MAX_PATH + 1]; inline Logger(HANDLE handle) : file_handle(handle), file_path{} { } inline Logger(const string& path) : Logger(path.c_str()) { } inline Logger(const wstring& path) : Logger(path.c_str()) { } inline Logger(const char* path) : file_handle(NULL) { wstring_convert<codecvt_utf8_utf16<wchar_t>> converter; wcscpy_s(file_path, MAX_PATH + 1, converter.from_bytes(path).c_str()); } inline Logger(const wchar_t* path) : file_handle(NULL) { wcscpy_s(file_path, MAX_PATH + 1, path); } private: inline void VerifyInitialize() { if ((file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) && file_path[0] != '\0') { file_handle = CreateFileW(file_path, FILE_GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(file_path, 0, NULL, FILE_END); } } public: inline void Log() { } template<typename ...Rest> inline void Log(const char* first, Rest... params) { VerifyInitialize(); if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) return; DWORD written; WriteFile(file_handle, first, static_cast<DWORD>(strlen(first)), &written, NULL); Log(params...); } template<typename ...Rest> inline void Log(const char first, Rest... params) { char str[2]; str[0] = first; str[1] = '\0'; Log(str, params...); } template<typename ...Rest> inline void Log(const string* first, Rest... params) { VerifyInitialize(); if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) return; DWORD written; WriteFile(file_handle, first->c_str(), static_cast<DWORD>(first->size()), &written, NULL); Log(params...); } template<typename ...Rest> inline void Log(const string& first, Rest... params) { Log(&first, params...); } template<typename ...Rest> inline void Log(const wstring* first, Rest... params) { Log(*first, params...); } template<typename ...Rest> inline void Log(const wstring& first, Rest... params) { Log(to_utf8(first), params...); } template<typename ...Rest> inline void Log(const wchar_t* first, Rest... params) { Log(wstring(first), params...); } template<typename ...Rest> inline void Log(const wchar_t first, Rest... params) { wchar_t str[2]; str[0] = first; str[1] = '\0'; Log(str, params...); } template<typename First, typename ...Rest> inline void Log(First first, Rest... params) { printf("%s\n", typeid(First).name()); if (is_const<First>::value) { stringstream stream; stream << first; Log(stream.str(), params...); } else Log(const_cast<const First>(first), params...); } inline ~Logger() { if (!(file_handle == NULL || file_handle == INVALID_HANDLE_VALUE)) { CloseHandle(file_handle); file_handle = NULL; } } };,c++,c++11,templates,constants,const-cast,C++,C++11,Templates,Constants,Const Cast,不调用专门化,而是调用最后一个通用的void日志(第一个,Rest…params),它使用stringstream,并将指针作为字符串而不是字符串本身写入 如果我从所有重载参数中删除const,当我调用main()时,它会工作,但是如果我用const char*替换sometext,则调用最后一个泛型void日志(首先,Rest…params)(即,删除const并不能解决问题) 因此,为了尽量做到两全其美,我尝试添加以下条件: template<typename First, typen

不调用专门化,而是调用最后一个通用的
void日志(第一个,Rest…params)
,它使用
stringstream
,并将指针作为字符串而不是字符串本身写入

如果我从所有重载参数中删除
const
,当我调用
main()
时,它会工作,但是如果我用
const char*
替换
sometext
,则调用最后一个泛型
void日志(首先,Rest…params)
(即,删除
const
并不能解决问题)

因此,为了尽量做到两全其美,我尝试添加以下条件:

template<typename First, typename ...Rest>
inline void Log(First first, Rest... params) {
    if (is_const<First>::value) {
        stringstream stream;
        stream << first;
        Log(stream.str(), params...);
    } else
         Log(const_cast<const First>(first), params...);
}
显然,
const\u cast(first)
实际上似乎并没有转换到
const
,即使
is\u const::value
确实返回了
false
。我也尝试过使用
std::as\u const
,但结果没有差异

为什么强制转换不起作用?请如何解决此问题?

仅用于将类型从常量强制转换为非常量。并且,只有在所述变量最初未声明为常量时,此方法才起作用

您不需要将某些内容强制转换为常量,只需将其复制到该类型的常量引用或常量值即可

const char* changeSecond(char* string, char change)
{
  string[0] = change;
  return string;
}
该函数将返回一个
常量字符*
,而无需强制转换。这也可以通过赋值来完成。

仅用于将类型从常量转换为非常量。这仅在所述变量最初未声明为常量时才起作用

您不需要将某些内容强制转换为常量,只需将其复制到该类型的常量引用或常量值即可

const char* changeSecond(char* string, char change)
{
  string[0] = change;
  return string;
}

该函数将返回一个
const char*
,而无需强制转换。这也可以通过赋值来完成。

如果
First
wchar\u t*
则强制转换将创建一个
wchar\u t*const
。强制转换不是类型名称的文本替换


因此,您创建了一个与任何专门化都不匹配的新类型,并获得对泛型
Log
函数的递归调用。

如果
第一个
wchar\u t*
则强制转换将创建一个
wchar\u t*常量,而不是
常量wchar\u*
。强制转换不是类型名的文本替换

因此,您创建了一个与任何专门化都不匹配的新类型,并获得了对泛型
Log
函数的递归调用。

除了“const-to-pointer”专门化之外,我为每个类型都添加了一个“pointer-to-const”专门化,并且一切正常!非常感谢:))除了“const-to-pointer”专门化之外,我为每种类型添加了一个“指向常量的指针”专门化,一切正常!万分感谢:))
const char* changeSecond(char* string, char change)
{
  string[0] = change;
  return string;
}