簡體   English   中英

折疊可變參數模板檢查成員函數的存在

[英]Folding variadic template checking for existence of a member function

我正在使用SFINAE慣用語來檢查類型是否具有帶有某些簽名的方法( function_name() )。 我實現的解決方案適用於單一類型,但我想使其(適用於可變參數模板)適用於多種類型。

template <typename... Other>
class has_foo {
   public:
    static constexpr bool value = has_foo<Other...>::value;
};

template <typename U, typename ...Other> // Error here
class has_foo {
   public:
    static constexpr bool value = has_foo<U>::value && has_foo<Other...>::value;
};

template <typename U>
class has_foo {
   private:
    template <typename T, T>
    struct helper;
    template <typename T>
    static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
    template <typename T>
    static std::uint16_t check(...);

   public:
    static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};

template <>
class has_foo<void> {
   public:
    static constexpr bool value = false;
};

我收到以下錯誤: too many template parameters in template redeclaration 我在這里做錯了什么?

template <typename U, typename ...Other>
class has_foo {
public:
    static constexpr bool value = has_foo<U>::value && has_foo<Other...>::value;
};

// partial template specialization
template <typename... Other>
class has_foo<void, Other...>{
public:
    static constexpr bool value = has_foo<void,Other...>::value;
};

// partial template specialization
template <typename U>
class has_foo<U,void> {
private:
    template <typename T, T>
    struct helper;
    template <typename T>
    static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
    template <typename T>
    static std::uint16_t check(...);

public:
    static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};

// partial template specialization
template <>
class has_foo<void> {
public:
    static constexpr bool value = false;
};

即使我不能測試它也不是mvce ,也許下面的代碼對您來說很好。

template<typename... Args>
class has_foo { };

template <typename U, typename ...Other>
class has_foo<U, Other...>: public has_foo<Other...> {
    template <typename t, t>
    struct helper;

    template <typename t>
    static std::uint8_t check(helper<int (*)(size_t), &t::function_name>*);

    template <typename t>
    static std::uint16_t check(...);

public:
    static constexpr bool value = (sizeof(check<U>(0)) == sizeof(std::uint8_t)) && has_foo<Other...>::value;
};

template <>
class has_foo<> {
public:
    static constexpr bool value = true;
};

template <>
class has_foo<void> {
public:
    static constexpr bool value = false;
};

這里是一個簡化的修訂版,也可以編譯:

#include <iostream>

template<typename... Args>
class has_foo { };

template <typename U, typename ...Other>
class has_foo<U, Other...>: public has_foo<Other...> {
public:
    static constexpr bool value = true && has_foo<Other...>::value;
};

template <>
class has_foo<> {
public:
    static constexpr bool value = true;
};

template <>
class has_foo<void> {
public:
    static constexpr bool value = false;
};

int main() {
    std::cout << has_foo<int, double, char>::value << std::endl;
    std::cout << has_foo<int, double, void>::value << std::endl;
    std::cout << has_foo<>::value << std::endl;
}

基本思想是定義一個可變參數結構,然后該結構專門用於使它起作用的所有所需情況,而不是看起來您感興趣的void

當前,對於示例中的最后一種情況,它返回true ,並且我不確定如何處理這種情況,因為您沒有給出任何建議。 無論如何,從上面的示例開始,您可以輕松地根據需要對其進行修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM