英文:
When I try to call SFINAE "createLog" function in C++ I get an Microsoft extension error
问题
我试图调用 SFINAE `createLog` 函数,该函数用于附加参数到 `log` 和 `message` 参数。编译器总是抛出错误 `use of member 'createLog' before its declaration is a Microsoft extension [-Werror,-Wmicrosoft-template]`。我知道这原本是一个警告,但因为我使用了 `-Werror` 参数,它被视为错误。
**我将要使用的代码:**
```cpp
template<typename ... Args>
static void RandomFunction(Args ... args) {
std::string log;
std::string message;
createLog("随机文本", log, message); //一切正常
(createLog(std::forward<Args>(args), log, message), ...); //编译器错误 "use of member 'createLog' before its declaration is a Microsoft extension [-Werror,-Wmicrosoft-template]"
}
"createLog" 函数声明:
template<typename T>
static std::enable_if_t<std::is_convertible_v<T, std::string>> createLog(T &arg, std::string &log, std::string &message) {
//我使用 std::string_view 作为 ANSI 转义码的容器
if (std::is_same_v<std::remove_reference_t<T>, std::string_view>) {
log.append(arg);
return;
}
log.append(arg);
message.append(arg);
}
template<typename T>
static std::enable_if_t<std::is_arithmetic_v<T>> createLog(T &arg, std::string &log, std::string &message) {
log.append(std::to_string(arg));
message.append(std::to_string(arg));
}
template<typename T>
static void createLog(...) {
Warn("类型 ", typeid(T).name(), " 无法被记录!");
}
我认为这个错误发生是因为编译器不知道模板参数包的类型,但我不知道如何解决这个问题。有什么想法吗?
编辑
我忘了提到,我遇到了另一个错误。
另一个错误:
no matching function for call to 'createLog'(createLog(std::forward<Args>(args), log, message), ...);
<details>
<summary>英文:</summary>
I'm trying to call SFINAE `createLog` function, which is used to append argument to `log` and `message` parameters. Compiler always throws `use of member 'createLog' before its declaration is a Microsoft extension [-Werror,-Wmicrosoft-template]` error. I know that it is originally warn, but it is treated as an error, because of the `-Werror` parameter I use.
**The code I would use:**
template<typename ... Args>
static void RandomFunction(Args ... args) {
std::string log;
std::string message;
createLog("random text", log, message); //all fine
(createLog(std::forward<Args>(args), log, message), ...); //Compiler error "use of member 'createLog' before its declaration is a Microsoft extension [-Werror,-Wmicrosoft-template]"
}
**The "createLog" function declaration:**
template<typename T>
static std::enable_if_t<std::is_convertible_v<T, std::string>> createLog(T &arg, std::string &log, std::string &message) {
//I use std::string_view as container for ANSI escape codes
if (std::is_same_v<std::remove_reference_t<T>, std::string_view>) {
log.append(arg);
return;
}
log.append(arg);
message.append(arg);
}
template<typename T>
static std::enable_if_t<std::is_arithmetic_v<T>> createLog(T &arg, std::string &log, std::string &message) {
log.append(std::to_string(arg));
message.append(std::to_string(arg));
}
template<typename T>
static void createLog(...) {
Warn("Type ", typeid(T).name(), " cannot be logged!");
}
I assume this error occurs, because the compiler doesn't know the types of template parameter pack, but I don't have any idea how to solve this. Any ideas?
**EDIT**
I forgot to mention, that I'm getting another error.
**The another error:**
`no matching function for call to 'createLog'(createLog(std::forward<Args>(args), log, message), ...);`
</details>
# 答案1
**得分**: 0
"Finally got it working. After some testing I found out that the error is caused by `constexpr` values, so I added `std::decay`, which seems to solve my problem.
**The updated code:**
```cpp
template<typename T>
static std::enable_if_t<std::is_same_v<std::decay_t<T>, std::string_view>>
createLog(T && arg, std::string& log, std::string& message) {
log.append(arg);
}
template<typename T>
static std::enable_if_t<std::is_convertible_v<std::decay_t<T>, std::string>>
createLog(T && arg, std::string& log, std::string& message) {
log.append(arg);
message.append(arg);
}
template<typename T>
static std::enable_if_t<std::is_arithmetic_v<std::decay_t<T>>>
createLog(T && arg, std::string& log, std::string& message) {
log.append(std::to_string(arg));
message.append(std::to_string(arg));
}
"
英文:
Finally got it working. After some testing I found out that the error is caused by constexpr
values, so I added std::decay
, which seems to solve my problem.
The updated code:
template<typename T>
static std::enable_if_t<std::is_same_v<std::decay_t<T>, std::string_view>>
createLog(T && arg, std::string& log, std::string& message) {
log.append(arg);
}
template<typename T>
static std::enable_if_t<std::is_convertible_v<std::decay_t<T>, std::string>>
createLog(T && arg, std::string& log, std::string& message) {
log.append(arg);
message.append(arg);
}
template<typename T>
static std::enable_if_t<std::is_arithmetic_v<std::decay_t<T>>>
createLog(T && arg, std::string& log, std::string& message) {
log.append(std::to_string(arg));
message.append(std::to_string(arg));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论