相关疑难解决方法(0)

是否可以编写模板来检查函数的存在?

是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?

这是我想写的一个简单例子:

template<class T>
std::string optionalToString(T* obj)
{
    if (FUNCTION_EXISTS(T->toString))
        return obj->toString();
    else
        return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)

所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.

c++ templates sfinae template-meta-programming

458
推荐指数
20
解决办法
14万
查看次数

"懒惰的人的enable_if"是合法的C++吗?

我经常使用一种技术,我称之为"懒人enable_if",我使用它decltype和逗号运算符来启用基于某些模板输入的函数.这是一个小例子:

template <typename F>
auto foo(F&& f) -> decltype(f(0), void())
{
    std::cout << "1" << std::endl;
}

template <typename F>
auto foo(F&& f) -> decltype(f(0, 1), void())
{
    std::cout << "2" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

随着--std=c++11,g ++ 4.7+和Clang 3.5+愉快地编译那段代码(并且它按照我的预期工作).但是,当使用MSVC 14 CTP5时,我得到这个错误抱怨foo已经定义:

错误错误C2995:'unknown-type foo(F &&)':函数模板已经定义了c ++ - scratch main.cpp 15

所以我的问题是:"懒人enable_if"是合法的C++还是这是一个MSVC错误?

c++ sfinae visual-c++ language-lawyer c++11

50
推荐指数
2
解决办法
3966
查看次数

std :: function的模板参数(签名)是不是它的类型?

鉴于以下代码,模糊性背后的原因是什么?我可以绕过它还是我必须保持(讨厌的)显式演员?

#include <functional>

using namespace std;

int a(const function<int ()>& f)
{
    return f();
}

int a(const function<int (int)>& f)
{
    return f(0);
}

int x() { return 22; }

int y(int) { return 44; }

int main()
{
    a(x);  // Call is ambiguous.
    a(y);  // Call is ambiguous.

    a((function<int ()>)x);    // Works.
    a((function<int (int)>)y); // Works.

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果我a()function<int ()>参数注释掉函数并a(x)在我的main中调用,则编译正确失败,因为它们之间的类型不匹配xfunction<int (int)>唯一a()可用函数的参数.如果编译器在这种情况下失败,为什么在存在这两个a()函数时会有任何歧义?

我试过VS2010和g ++ v.4.5.两者都给我完全相同的歧义.

c++ c++11 std-function

39
推荐指数
2
解决办法
5696
查看次数

基于模板参数类型调用函数

有两个"C"功能:

void fooA(const char*);
void fooW(const wchar_t*);
Run Code Online (Sandbox Code Playgroud)

然后有一个包装模板函数:

template<typename _TChar>
void foo(const _TChar* str)
{
     // call fooA or fooB based on actual type of _TChar
     // std::conditional .. ?
         // fooA(str); 
         // fooW(str);
}
Run Code Online (Sandbox Code Playgroud)

如果调用者调用foo("Abc"),则此模板函数应进行编译时调用fooA.同样,foo(L"Abc")应该做最后的调用fooW.

我怎么做?我想过使用std::conditional但不能成功.

我无法制作fooAfooB过载,因为这些是C函数.

c++ visual-c++ c++11 c++14

17
推荐指数
4
解决办法
5438
查看次数

如何编写适用于任何类型的集合对象的size()函数?

我需要一个简单的方法来获取类的对象的数量/长度/大小T这里T是某种集合类型,如中std::map,std::list,std::vector,CStringArray,CString,std::string,...

对于大多数标准类型,T::size()是正确答案,因为大多数MFC类T::GetSize()是正确的,因为CString它是T::GetLength().

我希望有一个像:

template <typename T> auto size(const T & t)
Run Code Online (Sandbox Code Playgroud)

...评估正确的成员函数调用.

看起来应该有一种简单的方法来调用一个traits模板,在T该模板上有一个size(const T & t)成员,它本身使用SFINAE存在或不存在,如果它存在,那么根据定义调用一个适当的方法t.size_function()来返回元素的数量.那个例子T.

我可以编写一个精心设计的has_member类型 - 特征模板 - 在stackoverflow上有一些例子 - 所有这些都让我觉得很复杂"必须有一个更简单的方法".使用C++ 17,似乎应该轻松优雅地解决这个问题?

这里这里的这些讨论似乎使用了一个不优雅的解决方案,其中一些答案使用预处理器宏来完成工作.这还有必要吗?

但是......当然,必须有一种方法可以使用这样一个事实,即在a上调用正确的成员函数T是可编译的,并且调用错误的函数无法编译 - 不能直接用于创建正确的类型特征包装器给定的类型T


我想要的是:

template <typename T>
auto size(const T & collection) …
Run Code Online (Sandbox Code Playgroud)

c++ mfc templates c++17

15
推荐指数
2
解决办法
1254
查看次数

为什么std :: is_function对于简单函数和lambdas返回false?

拥有以下代码:

#include <iostream>
#include <type_traits>

template <typename F,
          typename = typename std::enable_if<
                                              std::is_function< F >::value
                                            >::type>
int fun( F f ) // line 8
{
  return f(3);
}

int l7(int x)
{
  return x%7;
}

int main()
{
  auto l = [](int x) -> int{
    return x%7;
  };
  fun(l);  // line 23
  //fun(l7); this will also fail even though l7 is a regular function

  std::cout << std::is_function<decltype(l7)>::value ; // prints 1
}
Run Code Online (Sandbox Code Playgroud)

我会收到以下错误:

main2.cpp: In function ‘int main()’:
main2.cpp:23:8: error: …
Run Code Online (Sandbox Code Playgroud)

c++ lambda type-traits template-meta-programming c++11

7
推荐指数
2
解决办法
1497
查看次数

我怎么知道C++模板是容器还是类型?

我给出以下代码来表明我的问题:

template<T>
void my_fun(T &obj)
{
  if(obj is a type like float, std::string, double)
   {
       perform1()
  }
  if(obj is a container like std::vector, std::list)
  {
      perform2()
 } 
}
std::vector<int> abc;
my_fun(abc);
int d;
my_fun(d);
Run Code Online (Sandbox Code Playgroud)

然后我的问题,我怎么知道模板是指简单类型还是容器?谢谢.

c++ templates stl

7
推荐指数
2
解决办法
650
查看次数

表达式是在decltype中执行,还是只是检查验证?

通过使用Expression SFINAE,您可以检测是否支持某些操作员操作.

例如,

template <class T>
auto f(T& t, size_t n) -> decltype(t.reserve(n), void())
 { t.reserve(n); }
Run Code Online (Sandbox Code Playgroud)

我的问题是t.reserve(n)内部decltype被执行与否?

如果是,这是否意味着t.reserve(n)执行了两次,一次在内部decltype,另一次在函数体内?

如果没有,是否只是在编译期间检查验证?但是为什么它没有被执行,我认为逗号分隔表达式列表中的所有表达式都将被执行.

c++ templates sfinae c++11

6
推荐指数
1
解决办法
448
查看次数

如何检查成员函数是否具有const重载?

可以说我有

struct foo {
    void ham() {}
    void ham() const {}
};

struct bar {
    void ham() {}
};
Run Code Online (Sandbox Code Playgroud)

假设我有一个模板化函数,我可以判断给定类型是否具有const重载ham

c++ templates c++11

4
推荐指数
1
解决办法
255
查看次数

模板,decltype和非classtypes

我有一个像这样的函数定义

template <typename T>
auto print(T t) -> decltype(t.print()) {
    return t.print();
}
Run Code Online (Sandbox Code Playgroud)

这个想法是参数必须是类型,T并且必须具有该print函数.这个print函数可以返回任何东西,解释了它的需要decltype.例如,您可以这样做:

struct Foo
{
    int print()
    {
        return 42;
    }
};

struct Bar
{
    std::string print()
    {
        return "The answer...";
    }
};

...

std::cout << print(Foo()) << std::endl;    
std::cout << print(Bar()) << std::endl;
/* outputs: 
42
The answer...
*/
Run Code Online (Sandbox Code Playgroud)

我读到模板不能进行运行时实例化,并且您可以从类派生类,然后确定它们的类型以查看要使用的模板参数.但是,我如何为一个non-class类型做这个?这个想法是能够:

template <typename T>
T print(T t) {
    return t;
}
Run Code Online (Sandbox Code Playgroud)

同样,但这给了我模糊的过载错误.资格不起作用,即print<Foo>.另一个得到的问题是,如果我有一个类似的仿函数:

struct Foo
{
  virtual …
Run Code Online (Sandbox Code Playgroud)

c++ templates decltype c++11

3
推荐指数
1
解决办法
518
查看次数

将重载函数转换为专用函数模板

我有一个当前为不同数据类型重载的函数,并使用lambda(函数指针)初始化这些数据类型.我正在将它们转换为模板实例但尚未成功.

这是重载版本 -

#include <iostream>
using namespace std;


void doSome(int (*func)(int &)){
    int a;
    a = 5;
    int res = func(a);
    cout << a << "\n";
}


void doSome(int (*func)(double &)){
    double a;
    a = 5.2;
    int res = func(a);
    cout << a << "\n";
}


int main() {
    doSome([](int &a){
        a += 2;
        return 1;
    });

    doSome([](double &a){
        a += 2.5;
        return 1;
    });
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经采用了示例int并且double为了简化,它们可能是实际代码中的一些完全不同(和复杂)类型.


这是我尝试过的 -

#include <iostream>
using namespace std; …
Run Code Online (Sandbox Code Playgroud)

c++ lambda templates overloading c++14

2
推荐指数
1
解决办法
110
查看次数

查找模板相等运算符

我想编写一个代理类,该类具有模板值,并且可以与可以与模板进行比较的任何类进行比较。

template <class T>
class Proxy {
public:
  Proxy(T value) : _value(value) {}

  template <class U> // this should exist only if the T == U operator is defined
  bool operator==(U const& other) const  { return _value == other; }

  template <class U> // this should exist only if U == T is defined
  friend bool operator==(U const& first, Proxy<T> const& second) const  { return first == second._value; }

private:
  T _value;
};
Run Code Online (Sandbox Code Playgroud)

例如,由于这是合法代码:

bool compare(std::string first, std::string_view second) { …
Run Code Online (Sandbox Code Playgroud)

c++ templates

2
推荐指数
1
解决办法
70
查看次数

C++ 11在std :: is_same之后调用类型的构造函数以确认其类型

下面的代码没有编译,当我用类型Bar调用func时,当我用类型Foo调用func并且"无法将int转换为字符串"时,它会抱怨"无法将字符串转换为int".我以为我已经使用std :: is_same来判断该类型是否为Foo或Bar,为什么这似乎不起作用?什么是更好的方法来做到这一点?

class Foo {
  Foo(int foo){}
};

class Bar {
  Bar(string foo){}
};

template<typename T>
void func(){
  if(std::is_same<T, Foo>::value) {
    T t(1);
  } else {
    T t("aaa");
  }
}

func<Foo>();
func<Bar>();
Run Code Online (Sandbox Code Playgroud)

c++ c++11

0
推荐指数
1
解决办法
300
查看次数