在我尝试调用C++中的SFINAE “createLog”函数时,出现了一个Microsoft扩展错误。

huangapple go评论57阅读模式
英文:

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&#39;m trying to call SFINAE `createLog` function, which is used to append argument to `log` and `message` parameters. Compiler always throws `use of member &#39;createLog&#39; 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(&quot;random text&quot;, log, message); //all fine
(createLog(std::forward&lt;Args&gt;(args), log, message), ...); //Compiler error &quot;use of member &#39;createLog&#39; before its declaration is a Microsoft extension [-Werror,-Wmicrosoft-template]&quot;

}


**The &quot;createLog&quot; 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&#39;t know the types of template parameter pack, but I don&#39;t have any idea how to solve this. Any ideas?

**EDIT**

I forgot to mention, that I&#39;m getting another error.

**The another error:**

`no matching function for call to &#39;createLog&#39;(createLog(std::forward&lt;Args&gt;(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&lt;typename T&gt;
static std::enable_if_t&lt;std::is_same_v&lt;std::decay_t&lt;T&gt;, std::string_view&gt;&gt;
createLog(T &amp;&amp; arg, std::string&amp; log, std::string&amp; message) {
	log.append(arg);
}

template&lt;typename T&gt;
static std::enable_if_t&lt;std::is_convertible_v&lt;std::decay_t&lt;T&gt;, std::string&gt;&gt;
createLog(T &amp;&amp; arg, std::string&amp; log, std::string&amp; message) {
	log.append(arg);
	message.append(arg);
}

template&lt;typename T&gt;
static std::enable_if_t&lt;std::is_arithmetic_v&lt;std::decay_t&lt;T&gt;&gt;&gt;
createLog(T &amp;&amp; arg, std::string&amp; log, std::string&amp; message) {
	log.append(std::to_string(arg));
	message.append(std::to_string(arg));
}

huangapple
  • 本文由 发表于 2023年2月6日 04:52:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355431.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定