Gui*_*cot 7 c++ templates sfinae language-lawyer c++20
我生成了一个存在实现分歧的代码,我想知道哪个编译器是正确的以及为什么,或者标准的哪一部分允许这些编译器有所不同:
#include <type_traits>
#include <cstdio>
// Only deleted when the constraint is not met
template<typename T>
struct deleted {
template<typename U = T> requires (not std::is_integral_v<U>)
deleted() = delete;
template<typename U = T> requires std::is_integral_v<U>
deleted() {}
};
struct trigger_error {
template<typename F>
operator F () {
static_assert(not std::is_same_v<F, F>, "Cannot call f with floating point types");
return F{};
}
};
// Constrained function. Only callabale with integral types
// When called with something other than integral, display static assert.
// sfinae still applies even though the static assert is called.
template<typename T> requires std::is_integral_v<T>
void f(T) {}
template<typename T> requires (not std::is_integral_v<T>)
auto f(T, int = trigger_error{}, deleted<T> = {}) {};
// Do sfinae if f is callable. If callable, prints "integrals"
template<typename T> requires(requires(T t){f(t);})
auto use_constrains(T) -> void {
puts("integrals");
}
// Sfinae fails, print "floats" instead
template<typename T>
auto use_constrains(T) -> void {
puts("floats");
}
int main() {
use_constrains(1);
//f(1.3); // uncommenting triggers static assert
use_constrains(1.3);
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,代码甚至没有在 Clang 上编译,并且在调用已删除函数时出现硬错误deleted::deleted()。
MSVC 进行编译,但不执行 sfinae,也不执行硬错误,只是"integrals"在两次调用上进行打印。
由于这三种实现方式存在差异,我想知道谁是正确的以及为什么。sfinae 是否应用于参数默认值的表达式?
| 归档时间: |
|
| 查看次数: |
129 次 |
| 最近记录: |