Reputation: 7705
The following code does not compile. Is it even possible to pass an instance of Configuration<t, u>
as a template parameter? (to profit from optimization of constant expressions)
API:
template <int t, bool u>
struct Configuration {
static constexpr int commonValue = t;
static constexpr bool debug = u;
};
template <
template<int t, bool u> Configuration<t, u> &conf,
int x
>
class A {
public:
int doSomething() {
if (conf.debug) { // Optimize away if false
// ...
}
return x * conf.commonValue; // Optimize to e.g. 6 with `conf.commonValue` =
// 3, `x` = 2
}
};
The user of the API should be able to do:
int main() {
static constexpr Configuration<3, false> conf;
A<conf, 2> a;
A<conf, 5> b;
A<conf, 8> c;
std::cout << a.doSomething() << std::endl; // 6 (evaluated at compile time!)
std::cout << b.doSomething() << std::endl; // 15
std::cout << c.doSomething() << std::endl; // 24
}
Upvotes: 1
Views: 95
Reputation: 37661
Since the attributes of Configuration
are static
, you should use a template type parameter1:
template <class ConfT, int x>
class A {
public:
int doSomething() {
if (ConfT::debug) { // Optimize away if false
}
return x * ConfT::commonValue;
}
};
And then:
// Alias (not required):
using conf = Configuration<3, false>;
A<conf, 2> a;
A<conf, 3> b;
If you want non-static members, I don't think this is doable pre-C++17 (without passing template parameters of Configuration
to A
), but in C++17 you could do1:
template <auto const& conf, int x>
class A {
public:
int doSomething() {
if (conf.debug) { // Optimize away if false
}
return x * conf.commonValue;
}
};
But note that you can only pass references to variables with static storage duration.
1 In the first case, you can restrict the type to Configuration<...>
by specializing A
, in the second case, you can restrict the type of conf
using an extra template parameter with std::enable_if
.
You should also make the attributes constexpr
in Configuration
, not simply const
:
template <int t, bool u>
struct Configuration {
static constexpr int commonValue = t;
static constexpr bool debug = u;
};
Upvotes: 3