当前位置 : 主页 > 编程语言 > c++ >

c – 尝试制作在类中找到方法“大小”的元函数

来源:互联网 收集:自由互联 发布时间:2021-06-23
我正在尝试编写函数getSize(),它接受一些模板参数,尝试在此参数中查找方法或字段并返回size()或size. 我的代码是: #include iostream#include vector#include utility#include string#include type_traitstemplat
我正在尝试编写函数getSize(),它接受一些模板参数,尝试在此参数中查找方法或字段并返回size()或size.

我的代码是:

#include <iostream>
#include <vector>
#include <utility>
#include <string>
#include <type_traits>


template <typename T>
class has_size {
private:
  typedef char Yes;
  typedef Yes No[2];

  template <typename U, U> struct really_has;

  template<typename C> static Yes& Test(really_has <size_t (C::*)() const,     &C::size>*);
  template<typename C> static Yes& Test(really_has <size_t (C::*)(), &C::size>*);

  template<typename> static No& Test(...);

public:
    static bool const value = sizeof(Test<T>(0)) == sizeof(Yes);
};

template <class T>
size_t get_size(T t){

    size_t res = 0;
    if(has_size<T>::value){

        res = t.size();
    }else{

        res = t.size;
    }


    return res;

}

int main() {
    std::vector<float> v(10);
    std::cout << std::boolalpha << has_size<std::vector<float>>::value <<     std::endl;
    std::cout << std::boolalpha << has_size<std::string>::value << std::endl;
    size_t res = get_size(v);
    std::cout<< res;
    return 0;
}

函数has_size在我的示例中正确执行,但是当我尝试调用getSize时出现错误:

prog.cpp: In function ‘int main()’:
prog.cpp:47:24: error: the value of ‘v’ is not usable in a constant expression
  size_t res = get_size<v>;
                    ^
prog.cpp:43:21: note: ‘v’ was not declared ‘constexpr’
  std::vector<float> v(10);
                 ^
prog.cpp:47:15: error: cannot resolve overloaded function ‘get_size’ based on conversion to type ‘size_t {aka long unsigned int}’
  size_t res = get_size<v>;
           ^~~~~~~~~~~
所以稍微升级你的代码:(对于 c++11)

struct MyStruct{
    int size = 12;
};

// This function will compile only if has_size is true
template <class T,
            typename std::enable_if<has_size<T>::value, int>::type = 0>
size_t get_size(const T& t){
    return t.size();
}

// This function will compile only if has_size is FALSE (check negation !has_size)
template <class T,
            typename std::enable_if<!has_size<T>::value, int>::type = 0>
size_t get_size(const T& t){
    return t.size;
}

int main(){
    std::vector<float> v(10);
    std::cout << get_size(v) << std::endl;

    MyStruct my;
    std::cout << get_size(my) << std::endl;
    return 0;
}

关于std::enable_if的文件

所以我使用#4案例,通过模板参数启用.

因此,每个get_size函数的情况都将存在于最终程序中,具体取决于enable_if结果.所以编译器会忽略不满足我们的条件函数来编译.

所以稍微升级你的代码:(从c++17)

template <class T>
size_t get_size(const T& t){
    size_t res = 0;
    if constexpr(has_size<T>::value){
        res = t.size();
    }else{
        res = t.size;
    }
    return res;
}

int main(){
    std::vector<float> v(10);
    std::cout<< get_size(v) << std::endl;
    return 0;
}

所以更少的代码和更可读:)

该解决方案使用C 17 if constexpr的特征

为什么您的解决方案不起作用:

if(has_size<T>::value){ // <--- this is compile time result (has_size<T>::value) so always true or always false depends on template argument which is deduced from argument type
    res = t.size(); // this need to compile always, so if it is vector then ok if something else that doesn't have such method will fail to compile
}else{
    res = t.size; // this need to compile always, again as above
}

从较小的错误/改进:

>通过const&

网友评论