這篇文章中會有很多代碼,所以我想馬上為此道歉。與問題無關的代碼和大多數功能檔案已被洗掉,所以如果它變得相關,請隨時詢問。
我試圖讓 print 本質上充當 println 函式的“調度”,該函式對不同的資料型別有多個多載。在我的代碼中,一切都在一個cu命名空間中,因此它為什么存在于我的問題中。這里有一些代碼可以幫助理解這個系統是如何作業的。cu::ptext嘗試列印std::vector<cu::ptext>物件時,我的問題是特定于類的。
檔案:println.h
// All needed includes
namespace cu
{
template<typename Dp>
concept DefaultPrintable = requires(std::ostream& os, Dp ln)
{
os << ln;
};
}
#ifdef _WIN32
namespace cu
{
template<typename Po>
concept PrettyTextObject = std::derived_from<Po, console::ptext> && requires(Po text)
{
text.display();
};
template<typename Ip>
concept IteratorPrintable = !DefaultPrintable<Ip> && requires(Ip container)
{
std::begin(container);
std::end(container);
requires DefaultPrintable<decltype(*std::begin(container))> ||
PrettyTextObject<decltype(*std::begin(container))>;
};
}
#endif
namespace cu
{
template<DefaultPrintable Dp>
void println(Dp line)
{
std::cout << line;
}
}
#ifdef _WIN32
namespace cu
{
template<PrettyTextObject Po>
void println(const Po& pretty_text)
{
pretty_text.display();
}
}
#endif
namespace cu
{
template<IteratorPrintable Ip>
/**
Allows iteratiable objects with well-formed std::begin() and std::end() to
be printed, with each element being printed on its own line. THIS FUNCTION
SHOULD NOT BE ACCESSED DIRECTLY. Instead, use cu::print() or cu::prompt().
@param container The container whose elements should be printed.
*/
void println(Ip container)
{
// Figure out size of container
size_t elements_ct = 0;
for (auto el = std::begin(container); el != std::end(container); el)
elements_ct ;
if (elements_ct > 0)
{
using ItTy = decltype(std::begin(container));
struct ContainerLoop { ItTy itr; size_t i; };
for (ContainerLoop cl{ std::begin(container), 0 }; cl.itr != std::end(container); cl.itr)
{
println(*cl.itr);
if (cl.i < elements_ct - 1)
std::cout << '\n';
}
}
}
}
namespace cu
{
template<typename Ty>
concept Printable = requires(Ty ln)
{
println(ln);
};
}
檔案:列印.h
namespace cu
{
/**
Null case for print() which flushes the stream.
*/
inline void print()
{
std::cout << std::flush;
}
template<Printable Pt, Printable... Pts>
/**
Prints all arguments to console on their own line. All arguments must be
well-defined for cu::println([arg]).
@param line Current object to print to console
@param others All other objects to send through recursive function call
*/
void print(Pt line, Pts... others)
{
println(line);
std::cout << '\n';
print(std::forward<Pts>(others)...);
}
}
驅動程式代碼
cu::print("This is a test"); // <-- This line compiles fine
std::vector<std::string> stest{ "This", "is", "test" };
cu::print(stest); // <-- Also compiles fine
cu::print(cu::ptext("This is a test")); // <-- Compiles as well
std::vector<cu::ptext> ptest{ "This", "is", "test" };
cu::print(ptest); // <-- This line does not compile
要重現此錯誤:https
://godbolt.org/z/KroK4YehG
(具有以下編譯器輸出)
<source>:151:1: error: no matching function for call to 'print'
cu::print(ptest); // <-- This line does not compile
^~~~~~~~~
<source>:133:10: note: candidate template ignored: constraints not satisfied [with Pt = std::vector<cu::ptext>, Pts = <>]
void print(Pt line, Pts... others)
^
<source>:125:14: note: because 'std::vector<cu::ptext>' does not satisfy 'Printable'
template<Printable Pt, Printable... Pts>
^
<source>:111:9: note: because 'println(ln)' would be invalid: no matching function for call to 'println'
println(ln);
^
<source>:120:17: note: candidate function not viable: requires 0 arguments, but 1 was provided
inline void print()
^
1 error generated.
Compiler returned: 1
uj5u.com熱心網友回復:
問題就在這里
template<typename Ip>
concept IteratorPrintable = !DefaultPrintable<Ip> && requires(Ip container) {
std::begin(container);
std::end(container);
requires DefaultPrintable<decltype(*std::begin(container))> ||
PrettyTextObject<decltype(*std::begin(container))>;
};
decltype(*std::begin(container))給你一個參考型別,這會std::derived_from失敗PrettyTextObject。
解決方法是使用remove_reference洗掉參考,或者更簡單地說,只是使用ranges::range_value_t,它已經限制Ip為range.
template<typename Ip>
concept IteratorPrintable = !DefaultPrintable<Ip> &&
(DefaultPrintable<std::ranges::range_value_t<Ip>> ||
PrettyTextObject<std::ranges::range_value_t<Ip>>);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/491226.html
