是否有任何简单类型 sizeof(which) > 1 是有保证的?

Are there any simple types sizeof(which) > 1 is guaranteed?

在编写泛型代码时,我经常想要一个简单类型 T,保证 sizeof(T) > 1

例如:

template <typename T>
char test_foo(...);
template <typename T,
    typename = std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::foo)>>>
??? test_foo(int);
template <typename T>
struct has_foo : std::bool_constant<sizeof(test_foo<T>(0))!=1> {};

我有几个选择,但 none 是最理想的:

有什么想法吗?

sizeof(char) == 1 开始,您可以使用 char[2]。正如您所提到的,语法是

char (&test_foo())[2];

有效,但可能有点难以阅读。

这是一个主观的答案,但我认为

decltype(" ") test_foo();

相当可读。这里我们只使用 char[2].

类型的文字类型

我突然想到这应该行得通:

std::aligned_storage_t<2> & test_foo(int);

这没有引入新名称,而且可读性很好。

When writing generic code, I often want a simple type T for which sizeof(T) > 1 is guaranteed.

我认为你这样做的方式“错误”。

对于你的例子,你可以直接使用std::true_type/std::false_type

template <typename>
std::false_type test_foo(...);

template <typename T, std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::foo)>, int> = 0>
std::true_type test_foo(int);

template <typename T>
using has_foo = deltype(test_foo<T>(0));

如果您需要不同的 compile_time 类型内的数字,std::integral_constant 可能会有所帮助:

template <typename>
std::integral_constant<std::size_t, 0> test_foo(...);

template <typename T, std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::foo)>, int> = 0>
std::integral_constant<std::size_t, 42> test_foo(int);

template <typename T>
using has_foo = std::bool_constant<deltype(test_foo<T>(0))() == 42>;

char (&test_foo())[2];: too ugly

有更好的替代语法:

auto test_foo() -> char(&)[2];

但使用 typedef 会更具可读性 IMO:

template <std::size_t N>
using c_char_array = char[N];

然后

c_char_array<2>& test_foo();

以防万一。如果您尝试做检测功能存在的模板,这是如何完成的:

#include <iostream>
#include <type_traits>

class A {
public:
    int func() {return 1;}
};

class B {
};

template <typename T, typename = void>
struct has_func : std::false_type {};

template <typename T>
struct has_func<T, std::void_t<decltype(std::declval<T>().func())>>
    : std::true_type {};

template<typename T>
int wrap(T &t) {
    if constexpr (has_func<T>::value) {
        return t.func();
    } else {
        return 0;
    }
}


int main()
{
    A a;
    B b;
    std::cout << "A:" << wrap(a) << ", B:" << wrap(b) << "\n";
}