Hey guys,
I'd like to use concepts to verify that an interface is implented correctly.
Usally I would use virtual functions for this. However in this particular case the used implementation of the interface is known at compile time. There is no need for run time overheader like virtual functions.
//Interface
#pragma once
#include <concepts>
#include <string_view>
template <typename T>
concept IDmmy = requires(T a, const std::string_view b)
{
{ a.foo() };
{ a.bar(b) };
};
class DummyImpl
{
public:
#if 1
//not working with return type
template<typename T>
T foo();
template<typename S>
S bar(const std::string_view b);
#else
//working without return type
void foo();
void bar(std::string_view);
#endif
};
=> I'm explicitly ommiting return values of foo and bar because they depend on template parameters. I thought this would things much more difficult.
However the version with return types dos not work because the concept evalutates to false.
Could you help me out figure why?
The compound requirement on line 10 of your example { a.foo() };
Tests that the expression a.foo() is valid. It's not valid for your class because the compiler can't deduce what argument to substitute for the template parameter T in foo (or bar.)
This program exhibits the same root problem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class DummyImpl
{
public:
template<typename T> T foo() { return {}; }
};
int main()
{
DummyImpl a;
a.foo(); // error: no matching function for call to 'DummyImpl::foo()'
// ...
// note: template argument deduction/substitution failed:
// note: couldn't deduce template parameter 'T'
}
Often template arguments can be deduced, but not here. You'll have to specify it yourself: a.foo<int>()
To fix the original program, specify the template argument in the concept as well:
1 2 3 4 5 6 7
template <typename T, typename U, typename V>
concept IDmmy = requires(T a, const std::string_view b)
{
{ a.foo<U>() }; // wrong: should be { a.template foo<U>() };
{ a.bar<V>(b) }; // wrong: should be { a.template bar<V>(b) };
// or: { a.template foo<int>() };
};