[英]C++ concepts lite and type alias declaration
是否可以使用typedef
或using
在概念中聲明類型別名,如Concepts TS所提議的那樣? 如果我嘗試類似下面的MWE,代碼不編譯(使用gcc 6.2.1和-fconcepts
開關)
#include <type_traits>
template<typename T>
concept bool TestConcept ()
{
return requires(T t)
{
using V = T;
std::is_integral<V>::value;
};
}
int main()
{
return 0;
}
結果錯誤:
main.cpp: In function ‘concept bool TestConcept()’:
main.cpp:8:9: error: expected primary-expression before ‘using’
using V = T;
^~~~~
main.cpp:8:9: error: expected ‘}’ before ‘using’
main.cpp:8:9: error: expected ‘;’ before ‘using’
main.cpp:4:14: error: definition of concept ‘concept bool TestConcept()’ has multiple statements
concept bool TestConcept ()
^~~~~~~~~~~
main.cpp: At global scope:
main.cpp:11:1: error: expected declaration before ‘}’ token
}
^
不可以。根據TS的概念,要求是:
要求 :
簡單的要求
類型要求
化合物-要求
嵌套要求
簡單要求是表達式后跟a ;
類型要求類似於typename T::inner
。 另外兩個聽起來像顧名思義。
類型別名是聲明,而不是表達式,因此不符合要求的要求。
這對我來說是不必要的限制。 您是否知道是否存在合理的解決方法而不是一遍又一遍地編寫相同的復雜類型?
您可以將約束的實現推遲到另一個概念,將這些類型作為模板參數傳遞:
template<typename Cont, typename It, typename Value>
concept bool InsertableWith = requires(Cont cont, It it, Value value) {
// use It and Value as much as necessary
cont.insert(it, std::move(value));
};
template<typename Cont>
concept bool Insertable = requires {
// optional
typename Cont::const_iterator;
typename Cont::value_type;
} && InsertableWith<Cont, typename Cont::const_iterator, typename Cont::value_type>;
如果您正在考慮這樣做,我建議您在做出決定之前嘗試簡單的示例。 如何編寫概念和約束決定了編譯器如何報告錯誤,當然還有錯誤,這是使概念有用的重要部分。 在更難理解錯誤的同時更容易編寫我的概念並不是一種權衡,我會輕描淡寫。
例如,這就是為什么我冗余地添加了typename Cont::const_iterator;
作為一個明確的約束。 這使編譯器有機會報告此類型要求。 我也非常謹慎地選擇InsertableWith
作為概念的名稱:我可以輕松地使用detail::Insertable
,但涉及Insertable
和detail::Insertable
錯誤可能會因此而更加混亂。
最后請注意,這一切都依賴於編譯器的實現質量,所以我不認為任何方法暫時是明確的。 我鼓勵玩這個Coliru演示 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.