如何解决该计划是否违反 ODR?
考虑这个程序:
#include <type_traits>
template <typename T> constexpr bool g() { return true; }
template <typename T> std::enable_if_t< g<T>()> f() {}
template <typename T> std::enable_if_t<!g<T>()> f() {}
int main() { f<int>(); }
各种版本的GCC和Clang都可以接受,但是MSVC不能接受,编译失败提示错误
1>D:\x.cpp(5,49): error C2995: 'enable_if<0,void>::type f(void)': function template has already been defined
1>D:\x.cpp(4): message : see declaration of 'f'
1>D:\x.cpp(4,49): error C3861: 'f': identifier not found
第一条错误消息向我暗示了 ODR 违规 - 但如果该程序是格式错误的 NDR,我需要帮助理解为什么会这样。我已经检查了标准草案中的 [temp.over.link],但我不确定我是否正确解释了它。据我了解,该程序是可以的,因为这些函数模板具有不同的签名。
万一这个程序是正确的,为什么 MSVC 拒绝它?
解决方法
MSVC 在这里有一个错误。
对于大多数函数,参数的等价性足以指示错误。对于模板,还涉及返回类型表达式。
MSVC 似乎忽略了返回类型表达式,并生成了一个错误,好像它可以忽略它一样。
g<T>()
/!g<T>()
部分可以拆分为 sizeof(T)==1
和 sizeof(T)!=1
以移除另一个混淆特征(事实上,这两者之一实际上无法实例化).
试试这个:
template <typename T,std::enable_if_t<g<T>(),bool> =true> void f() {}
template <typename T,std::enable_if_t<!g<T>(),bool> =true> void f() {}
它适用于所有 3 个编译器。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。