模板:检测成员函数是否存在时出错以及我的修复

时间:2015-07-24 21:45:07

标签: c++ templates template-meta-programming sfinae

我正在使用 The C ++ Programming Language,4th Edition 28.4.4 部分中的以下代码:

#pragma once
#include <type_traits>

struct substitution_failure {}; // represent a failure to declare something

template<typename T>
struct substitution_succeeded : std::true_type {};

template<>
struct substitution_succeeded<substitution_failure> : std::false_type {};

template<typename T>
struct get_f_result
{
private:
    template<typename X>
    static auto check( X const& x ) −> decltype( f( x ) ); // can call f(x)
    static substitution_failure check( ... ); // cannot call f(x)
public:
    using type = decltype( check( std::declval<T>() ) );
};

template<typename T>
struct has_f : substitution_succeeded<typename get_f_result<T>::type> {};

将所述代码复制并粘贴到 Visual Studio Community 2015 中,我收到以下错误:

\learning_cpp\c28.h(17): error C2988: unrecognizable template declaration/definition

这引出了我的观点:

static auto check( X const& x ) −> decltype( f( x ) ); // can call f(x)

通过查看 std :: is_assignable 如何工作,我想出了以下代码,它似乎给了我正确的结果(请告诉我,如果我做错了什么!):

// similar declarations/definitions for substitution_failure &
// substitution_succeeded aside from struct names

template<typename T>
struct get_my_func_result
{
private:
    template <typename U>
    static auto check( U const& ) -> decltype( (decltype(std::declval<U>().my_func())) (std::declval<U>().my_func()), substitution_success<U>() );

    static substitution_fail check( ... );

public:
    using type = decltype( check( std::declval<T>() ) );
};

template<typename T>
struct has_my_func : substitution_success<typename get_my_func_result<T>::type> {};

的main.cpp

// includes

struct A {};
struct B { void my_func(); };
struct C : public B {};

int main()
{
    has_my_func<A>::value; // false
    has_my_func<B>::value; // true
    has_my_func<C>::value; // true
    return 0;
}

问题。

  1. 为什么第一个版本失败了?我意识到我正在尝试检测成员函数,这就是为什么std :: declval()以及修复中使用的其他功能,但书籍版本是否也有效?它只是我的编译器吗?
  2. 修改

    答案:失败的行在复制粘贴操作中具有无效字符:

    static auto check( X const& x ) −> decltype( f( x ) ); // can call f(x)
    

    应该是:

    static auto check( X const& x ) -> decltype( f( x ) ); // can call f(x)
    

    破折号角色是罪魁祸首。但是,这似乎还没有工作,因为我们从未指定检查f(x)的存在的类型。我没有尝试对这段代码进行任何进一步的修复,因为我的解决方法似乎工作正常。

    结束编辑

    1. 我做的事情在100%的时间都不对吗?是否有任何东西可以通过它,但这不会超过书籍版本?我正在考虑推广我的版本。

0 个答案:

没有答案