我想使用Concepts TS來幫助我處理數據約束。我將討論在p0121r0中討論的概念,並且我正在使用GCC 6.2進行測試。C++ TS概念和訪問器
藉此簡單的代碼:
template<typename T>
concept bool test_is_available = requires(T t) {
t.test;
{ t.test++ };
{ t.test-- };
};
template<test_is_available T>
struct Tester
{
T t;
};
我必須傳遞給結構測試儀與測試屬性,它是可遞增和decrementable一個類型。好。
struct A
{
unsigned test;
}
Tester<A> a;
按預期工作。很明顯,下面的一個將不起作用:
struct B
{
std::string test;
};
struct C
{
unsigned not_test;
};
Tester<B> b; // error: test++ and test-- are ill formed
Tester<C> c; // error: no test available
現在,真正的問題:爲什麼下面的一個不工作?
class D
{
unsigned test;
};
Tester<D> d; // error: private???
我試圖挖掘到STD紙,但我無法理解這是正常現象,如果STD本身缺少這種可能性,如果編譯器不能正常工作......
或者我可能需要宣佈某種友誼,但是有什麼意義呢?在這種情況下,概念約束不需要被訪問者約束 ...
任何關於這裏發生了什麼的想法?
編輯: 通過一個簡單的例子並不總是容易給出這個問題的想法。這一個是更復雜一點,但更類似於真實的案例:
#include <cassert>
#include <utility>
template<typename T>
concept bool Countable = requires(T t) {
t.counter;
{ ++t.counter };
{ --t.counter };
//{ t.load(auto&&...) } -> void; <-- I am not sure how to handle this
{ t.unload() } -> void;
};
template<Countable T>
class Scoper
{
public:
template<typename... Args>
Scoper(T& t, Args... args) : m_t(&t)
{
++t.counter;
t.load(std::forward<Args>(args)...);
}
~Scoper()
{
--m_t->counter;
m_t->unload();
}
private:
T* m_t;
};
class Scopeable
{
public:
unsigned getCounter() const
{
return counter;
}
//private:
//template<Countable> friend class Scoper; <-- does not work
void load(char, int) {}
void unload() {}
unsigned counter = 0;
};
int main()
{
Scopeable scopeable;
assert(scopeable.getCounter() == 0);
{
Scoper<Scopeable> scoper(scopeable, 'A', 2);
assert(scopeable.getCounter() == 1);
}
assert(scopeable.getCounter() == 0);
}
正如你所看到的,很明顯,計數器,負載和卸載必須是私人/保護,而且他們只需要從Scoper訪問。 如果我使用一個抽象基類,我只能約束計數器和卸載,但不負載(爲此,你可以看到,我不知道如何處理正確的語法......)。
也許這不會改變你的答案,但問題可能是一點點清潔。
因此,你只是說沒有辦法*要求*的會員,沒有可訪問性限制? – dodomorandi
我_think_你可以把'Tester'類標記爲朋友,它也應該提供這個概念的私人訪問。儘管我沒有太多的概念,但我可能是錯的。 – Bitwize
@dodomorandi這是'私人'的點。 – Barry