我在使用 ADL 的概念方面遇到了問題。
編輯 1:我提到 ADL,因為parse函式應該用用戶定義的型別多載。
這個from_string_view_parsable概念沒有看到parse下面的功能,因為 ADL 不適用于它們。
函式需要在概念定義之前定義或前向宣告,但是對于第二個多載,存在回圈依賴,因此無法完成。
https://godbolt.org/z/frn1jKv5E
#include <sstream>
#include <optional>
template <typename T>
concept from_string_view_parsable = requires(std::string_view sv, T& x) {
{ parse(sv, x) };
};
void parse(std::string_view input, int& out)
{
auto ss = std::stringstream{};
ss << input;
ss >> out;
}
template <from_string_view_parsable T>
requires std::default_initializable<T>
void parse(std::string_view input, std::optional<T>& out)
{
out = T{};
parse(input, *out);
}
template <from_string_view_parsable T>
void use_parse(T& t) {
parse("123", t);
}
int main() {
std::optional<int> x;
use_parse(x);
}
我試圖做的事情從根本上是錯誤的,或者是否有任何解決方法可以讓我這樣做?
uj5u.com熱心網友回復:
你可以將requires運算式推遲到一個型別特征,它可以被向前宣告:
#include <sstream>
#include <optional>
#include <string_view>
#include <type_traits>
template <typename T>
struct is_from_string_view_parsable;
template <typename T>
concept from_string_view_parsable = is_from_string_view_parsable<T>::value;
void parse(std::string_view input, int& out)
{
auto ss = std::stringstream{};
ss << input;
ss >> out;
}
template <from_string_view_parsable T>
requires std::default_initializable<T>
void parse(std::string_view input, std::optional<T>& out)
{
out = T{};
parse(input, *out);
}
template <from_string_view_parsable T>
void use_parse(T& t) {
parse("123", t);
}
template <typename T>
struct is_from_string_view_parsable : std::bool_constant<
requires(std::string_view sv, T& x) {
{ parse(sv, x) };
}
> {};
int main() {
std::optional<int> x;
use_parse(x);
}
現在,我不確定這是否違反任何規則,但我認為不應該。請注意約束的評估不會在程式的不同點發生變化。
uj5u.com熱心網友回復:
由于概念不能向前宣告的定義from_string_view_parsable必須出現后的std::optional過載。
相反,您可以使用requires 子句(或static_assert)來約束parse(intput, *out)must be well-formed ,如下所示:
#include <sstream>
#include <optional>
void parse(std::string_view input, int& out)
{
auto ss = std::stringstream{};
ss << input;
ss >> out;
}
template <std::default_initializable T>
void parse(std::string_view input, std::optional<T>& out)
requires requires { parse(input, *out); }
{
out = T{};
parse(input, *out);
}
template <typename T>
concept from_string_view_parsable = requires(std::string_view sv, T& x) {
{ parse(sv, x) };
};
template <from_string_view_parsable T>
void use_parse(T& t) {
parse("123", t);
}
int main() {
std::optional<int> x;
use_parse(x);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/402521.html
標籤:
下一篇:從單獨的類訪問JPanel組件
