vpo*_*yev 5 c++ gcc clang language-lawyer enable-if
我一直enable_if以这种近似的方式使用各种版本的 GCC(最高 5.2):
template< bool b, std::enable_if_t< b >... >
void fn() { std::cout << 1 << std::endl; }
template< bool b, std::enable_if_t< !b >... >
void fn() { std::cout << 2 << std::endl; }
// ...
fn< true >();
fn< false >();
Run Code Online (Sandbox Code Playgroud)
但是,事实证明,Clang 3.7 不接受这一点(“调用‘fn’是不明确的”)。
Q1. 谁是对的,为什么?
当然,还有其他方法可以做到这一点,但我有点不喜欢
template< bool b >
std::enable_if_t< b, void > fa() { std::cout << 1 << std::endl; }
// ...
Run Code Online (Sandbox Code Playgroud)
以及它的同类,使函数签名的正常部分变得不那么可读,并且
template< bool b, std::enable_if_t< b, int > = 0 >
void fd() { std::cout << 1 << std::endl; }
// ...
Run Code Online (Sandbox Code Playgroud)
用于涉及不相关的元素(类型和值)。
Q2。还有哪些其他(正确的、更易读的、更少黑客/怪异的)使用enable_if/enable_if_t的方法?
根据标准14.1/p7模板参数[temp.param](重点是我的):
非类型模板参数不得声明为具有浮点、类或void 类型。
因此,您的代码片段格式不正确。因此,GCC 在这一点上是错误的。
但是,如果您更改为:
template< bool b, std::enable_if_t< b, int>... >
void fn() { std::cout << 1 << std::endl; }
template< bool b, std::enable_if_t< !b, int>... >
void fn() { std::cout << 2 << std::endl; }
Run Code Online (Sandbox Code Playgroud)
限制已解除,该代码是合法的,应该被接受。显然,Clang 似乎也拒绝了这段代码。恕我直言,这是一个 Clang 错误。
据我发现,类似的错误已被报告23840。
现在对于实际部分,我不知道这是否实用/不那么黑客/不那么奇怪,但你可以执行以下操作:
template< bool b, std::enable_if_t< b, int> = 0 >
void fn() { std::cout << 1 << std::endl; }
template< bool b, std::enable_if_t< !b, int> = 0 >
void fn() { std::cout << 2 << std::endl; }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |