![](/img/trans.png)
[英]C++ friend function template overloading and SFINAE different behaviors in clang++, g++, vc++ (C++14 mode)
[英]C++ Concepts/SFINAE: clang and MSVC/G++ different results for out of line function definition with template and Concept/SFINAE
我正在定義一個 class 的構造函數,它在概念或 SFINAE 的幫助下,限制檢查傳入迭代器的底層類型與我的 class 中定義的 node_type 的類型等價性。
但是,嘗試了一些與is_same<>, is_same_v<>, enable_if<>
和same_as<>
概念的組合,離線定義將始終在至少一個主要編譯器上產生編譯時錯誤。 目前下面的代碼片段在 MSVC/g++ 上沒有看到錯誤,但 clang 抱怨,全部使用最新版本(分別為 19.28、11.1、12.0)。 誰能澄清這里有什么問題? 謝謝。
編輯:
使用 C++20 在 Godbolt 上的代碼如下,MSVC/g++ ok,clang 錯誤https://godbolt.org/z/fdqEYxKh8
代碼未在下面顯示,但在 Godbolt 上使用 C++11 SFINAE、MSVC/clang ok、g++ 錯誤https://a/zYn8r7/
#include <stdio.h>
#include <iterator>
#include <array>
#include <concepts>
#include <cstdlib>
template <typename FPType, std::size_t N>
class PointND {
private:
std::array<FPType, N> coords_;
};
template <typename FPType, std::size_t N, typename ElemType>
class Tree {
public:
struct node_type {
PointND<FPType, N> key;
ElemType value;
};
template <std::random_access_iterator RAI>
requires std::same_as<typename std::iterator_traits<RAI>::value_type,
typename Tree<FPType, N, ElemType>::node_type>
Tree(RAI, RAI);
};
template <typename FPType, std::size_t N, typename ElemType>
template <std::random_access_iterator RAI>
requires std::same_as<typename std::iterator_traits<RAI>::value_type,
typename Tree<FPType, N, ElemType>::node_type>
Tree<FPType, N, ElemType>::Tree(RAI begin, RAI end) {
}
此行錯誤::45:30: 錯誤: 'Tree<FPType, N, ElemType>' 的行外定義與 'Tree<FPType, N, ElemType>' 中的任何聲明都不匹配
Tree<FPType, N, ElemType>::Tree(RAI begin, RAI end) {
在 C++11 示例中,添加-fchecking
和 gcc 會說:
<source>:52:51: internal compiler error: canonical types differ for identical types 'std::enable_if<(std::is_same<typename std::iterator_traits<_InputIterator>::iterator_category, std::random_access_iterator_tag>::value && std::is_same<typename std::iterator_traits<_InputIterator>::value_type, typename Tree<FPType, N, ElemType>::node_type>::value), int>' and 'std::enable_if<(std::is_same<typename std::iterator_traits<_InputIterator>::iterator_category, std::random_access_iterator_tag>::value && std::is_same<typename std::iterator_traits<_InputIterator>::value_type, Tree<FPType, N, ElemType>::node_type>::value), int>'
52 | Tree<FPType, N, ElemType>::Tree(RAI begin, RAI end) {
| ^
...
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
gcc 無法編譯這是一個編譯器錯誤。
我懷疑但不能證明 clang 在 C++20 代碼上的行為也是一個錯誤。
有一個簡單的解決方法。 這些錯誤與解釋名稱有關,尤其是在不完整的 class 的上下文中的嵌套 class。 所以...將類型移動到命名空間 scope:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.