std::enable_if 更改成员 *变量* declaration/type
std::enable_if to change member *variable* declaration/type
我查看了一些类似的问题,例如 this one and ,并且我了解如何使用成员 函数 的 enable_if。
这是一个工作示例:
#include <iostream>
template <int size>
class Test
{
private:
constexpr static bool ENABLE = (size < 10);
public:
template <bool E = ENABLE, typename std::enable_if<E, int>::type = 0>
static int foo();
template <bool E = ENABLE, typename std::enable_if<!E, int>::type = 0>
constexpr static int foo();
};
template <int size>
template <bool E, typename std::enable_if<E, int>::type>
int Test<size>::foo()
{
return 7;
}
template <int size>
template <bool E, typename std::enable_if<!E, int>::type>
constexpr int Test<size>::foo()
{
return 12;
}
int main()
{
Test<5> v1;
Test<15> v2;
std::cout << v1.foo() << "\n";
std::cout << v2.foo() << "\n";
}
但是,当我尝试稍微修改代码以使其适用于成员 variables 时,我遇到了严重的重新声明错误。这甚至可能与变量有关,我只是错过了一些简单的东西吗?
这是我有问题的示例代码:
#include <iostream>
template <int size>
class Test
{
private:
constexpr static bool ENABLE = (size < 10);
public:
template <bool E = ENABLE, typename std::enable_if<E, int>::type = 0>
static int foo;
template <bool E = ENABLE, typename std::enable_if<!E, int>::type = 0>
constexpr static int foo = 12;
};
template <int size>
template <bool E, typename std::enable_if<E, int>::type>
int Test<size>::foo = 7;
template <int size>
template <bool E, typename std::enable_if<!E, int>::type>
constexpr int Test<size>::foo;
int main()
{
Test<5> v1;
Test<15> v2;
std::cout << v1.foo<> << "\n";
std::cout << v2.foo<> << "\n";
}
提前致谢,任何help/guidance不胜感激!
您可以使用提供成员 foo
:
的条件基础 class 来达到预期的效果
template<int FOO_INIT>
struct TestImpl1 {
static int foo;
};
template<int FOO_INIT>
int TestImpl1<FOO_INIT>::foo = FOO_INIT;
template<int FOO_INIT>
struct TestImpl2 {
constexpr static int foo = FOO_INIT;
};
template<int FOO_INIT>
constexpr int TestImpl2<FOO_INIT>::foo;
template<int size>
struct Test
: std::conditional<
(size < 10),
TestImpl1<7>,
TestImpl2<12>
>::type
{};
int main() {
Test<5> v1;
Test<15> v2;
std::cout << v1.foo << "\n";
std::cout << v2.foo << "\n";
// constexpr int i1 = v1.foo; // Fails to compile because Test<5>::foo is not constexpr.
constexpr int i2 = v2.foo; // Compiles because Test<15>::foo is constexpr.
}
如果您只对静态成员变量执行此操作,您仍然有机会通过使用块作用域静态变量使它们起作用。这样你的 foo
就变成了一个函数,所以你可以在它们上面应用 SFINAE。
#include <iostream>
template <int size>
class Test
{
private:
constexpr static bool ENABLE = (size < 10);
public:
template <bool E = ENABLE, typename std::enable_if<E, int>::type = 0>
static int& foo();
template <bool E = ENABLE, typename std::enable_if<!E, int>::type = 0>
constexpr static int foo();
};
template <int size>
template <bool E, typename std::enable_if<E, int>::type>
int& Test<size>::foo() {
static int foo_impl = 7;
return foo_impl;
}
template <int size>
template <bool E, typename std::enable_if<!E, int>::type>
constexpr int Test<size>::foo() {
return 12;
}
int main()
{
Test<5> v1;
Test<15> v2;
std::cout << v1.foo() << "\n";
std::cout << v2.foo() << "\n";
}
我查看了一些类似的问题,例如 this one and
这是一个工作示例:
#include <iostream>
template <int size>
class Test
{
private:
constexpr static bool ENABLE = (size < 10);
public:
template <bool E = ENABLE, typename std::enable_if<E, int>::type = 0>
static int foo();
template <bool E = ENABLE, typename std::enable_if<!E, int>::type = 0>
constexpr static int foo();
};
template <int size>
template <bool E, typename std::enable_if<E, int>::type>
int Test<size>::foo()
{
return 7;
}
template <int size>
template <bool E, typename std::enable_if<!E, int>::type>
constexpr int Test<size>::foo()
{
return 12;
}
int main()
{
Test<5> v1;
Test<15> v2;
std::cout << v1.foo() << "\n";
std::cout << v2.foo() << "\n";
}
但是,当我尝试稍微修改代码以使其适用于成员 variables 时,我遇到了严重的重新声明错误。这甚至可能与变量有关,我只是错过了一些简单的东西吗?
这是我有问题的示例代码:
#include <iostream>
template <int size>
class Test
{
private:
constexpr static bool ENABLE = (size < 10);
public:
template <bool E = ENABLE, typename std::enable_if<E, int>::type = 0>
static int foo;
template <bool E = ENABLE, typename std::enable_if<!E, int>::type = 0>
constexpr static int foo = 12;
};
template <int size>
template <bool E, typename std::enable_if<E, int>::type>
int Test<size>::foo = 7;
template <int size>
template <bool E, typename std::enable_if<!E, int>::type>
constexpr int Test<size>::foo;
int main()
{
Test<5> v1;
Test<15> v2;
std::cout << v1.foo<> << "\n";
std::cout << v2.foo<> << "\n";
}
提前致谢,任何help/guidance不胜感激!
您可以使用提供成员 foo
:
template<int FOO_INIT>
struct TestImpl1 {
static int foo;
};
template<int FOO_INIT>
int TestImpl1<FOO_INIT>::foo = FOO_INIT;
template<int FOO_INIT>
struct TestImpl2 {
constexpr static int foo = FOO_INIT;
};
template<int FOO_INIT>
constexpr int TestImpl2<FOO_INIT>::foo;
template<int size>
struct Test
: std::conditional<
(size < 10),
TestImpl1<7>,
TestImpl2<12>
>::type
{};
int main() {
Test<5> v1;
Test<15> v2;
std::cout << v1.foo << "\n";
std::cout << v2.foo << "\n";
// constexpr int i1 = v1.foo; // Fails to compile because Test<5>::foo is not constexpr.
constexpr int i2 = v2.foo; // Compiles because Test<15>::foo is constexpr.
}
如果您只对静态成员变量执行此操作,您仍然有机会通过使用块作用域静态变量使它们起作用。这样你的 foo
就变成了一个函数,所以你可以在它们上面应用 SFINAE。
#include <iostream>
template <int size>
class Test
{
private:
constexpr static bool ENABLE = (size < 10);
public:
template <bool E = ENABLE, typename std::enable_if<E, int>::type = 0>
static int& foo();
template <bool E = ENABLE, typename std::enable_if<!E, int>::type = 0>
constexpr static int foo();
};
template <int size>
template <bool E, typename std::enable_if<E, int>::type>
int& Test<size>::foo() {
static int foo_impl = 7;
return foo_impl;
}
template <int size>
template <bool E, typename std::enable_if<!E, int>::type>
constexpr int Test<size>::foo() {
return 12;
}
int main()
{
Test<5> v1;
Test<15> v2;
std::cout << v1.foo() << "\n";
std::cout << v2.foo() << "\n";
}