可能重复:
是否可以编写C++模板来检查函数是否存在?
是否可以使用boost类型特征或某些其他机制来检查特定模板参数是否具有运算符/函数,例如,std::vector作为模板参数具有operator[],而std::pair不是.
我可以使用SFINAE(或其他技术)进行using声明,而私有派生自模板类吗?为了更好地理解,请参阅以下代
#include <iostream>
struct S1 {
void f() { std::cout << "S1::f\n"; }
};
struct S2 {
void f() { std::cout << "S2::f\n"; }
void g() { std::cout << "S2::g\n"; }
};
template <class T>
struct D : private T {
using T::f;
// using T::g; // need this only if T provides g() function
};
int main() {
D<S1>().f(); // ok. Prints 'S1::f'
D<S2>().f(); // ok. Prints 'S2::f'
D<S2>().g(); // fail. But wants to be ok and …Run Code Online (Sandbox Code Playgroud) 我有一个仿函数,它运行在类似U元素类型的容器上T
template<typename T, template<typename...> class U>
class asserter
{
public:
asserter(U<T> &c) : container(c) { };
void operator()(T lhs)
{
CU_ASSERT(container.find(lhs) != container.end());
};
private:
U<T> &container;
};
Run Code Online (Sandbox Code Playgroud)
我可以用它作为
std::set<std::string> a, c;
...
asserter<std::string, std::set> ass(c);
for_each(a.begin(), a.end(), ass);
Run Code Online (Sandbox Code Playgroud)
我们std::includes()暂时无视的地方.
如果容器U::find()是定义的容器,这很有用.如果不是我想回归std::find().另一方面U::find(),std::find()如果它可用,我宁愿使用它.
在C++ 11中(如果需要,可以U::find()是17)我可以确定U是否可用(可能限制为STL),如果是,请使用它,否则使用std::find()?
我注意到,GCC 和 MSVC 都对以下代码感到满意:
#include <iostream>
void foo(...);
int main()
{
foo();
}
void foo(...)
{
std::cout << "foo\n";
}
Run Code Online (Sandbox Code Playgroud)
更具体地说,代码在 GCC 6.2.0 和 Visual Studio 2015 下运行。
我知道,C需要至少一个命名参数省略号,它允许处理使用专门的任意数量的参数之前va_start,va_args和va_end宏从<stdarg.h>(这里<cstdarg>)头。否则,它甚至不会编译。
C++ 是否对“纯省略号”形式有一些特殊处理,或者它不适合获取参数,即它是允许的,但完全不切实际?
我有一个调用成员函数的模板。我如何检查static_assert该方法是否存在?
struct A {
};
struct B {
int foo() { return 42; } };
template <typename T> struct D {
static_assert(/* T has foo */, "T needs foo for reasons");
int bar() {
return t.foo();
}
T t; };
int main() {
D<A> d;
std::cout << d.bar() << std::endl;
return 0; }
Run Code Online (Sandbox Code Playgroud)
我知道这只会产生 A 没有 foo 的编译器错误,但我想检查并使用static_assert.
我生成了一个存在实现分歧的代码,我想知道哪个编译器是正确的以及为什么,或者标准的哪一部分允许这些编译器有所不同:
#include <type_traits>
#include <cstdio>
// Only deleted when the constraint is not met
template<typename T>
struct deleted {
template<typename U = T> requires (not std::is_integral_v<U>)
deleted() = delete;
template<typename U = T> requires std::is_integral_v<U>
deleted() {}
};
struct trigger_error {
template<typename F>
operator F () {
static_assert(not std::is_same_v<F, F>, "Cannot call f with floating point types");
return F{};
}
};
// Constrained function. Only callabale with integral types
// When called with something other than integral, display static assert. …Run Code Online (Sandbox Code Playgroud) 有没有办法,大概是使用模板,宏或两者的组合,我可以通常将一个函数应用于不同类的对象,但如果它们没有特定的功能,它们会以不同的方式响应吗?
我特别想要应用一个函数,如果对象具有该函数,将输出对象的大小(即集合中的对象数),但如果对象没有,则将输出一个简单的替换(例如"N/A") "T.即
NO_OF_ELEMENTS( mySTLMap ) -----> [ calls mySTLMap.size() to give ] ------> 10
NO_OF_ELEMENTS( myNoSizeObj ) --> [ applies compile time logic to give ] -> "N/A"
Run Code Online (Sandbox Code Playgroud)
我希望这可能类似于静态断言,尽管我显然想要编译不同的代码路径而不是在构建阶段失败.
编辑:我的问题的简短回答是,我对SFINAE可以做什么有错误的看法,而且根本没有检查函数体:sfinae是否实例化了一个函数体?
我有一个与此类似的问题:是否可以编写模板来检查函数的存在?
不同之处在于我不仅想检查函数是否存在,而且我还想知道它是否真的会通过SFINAE.这是我想要完成的一个例子:
struct A
{
void FuncA() { std::cout << "A::FuncA" << std::endl; }
};
struct B
{
void FuncA() { std::cout << "B::FuncA" << std::endl; }
void FuncB() { std::cout << "B::FuncB" << std::endl; }
};
template<typename T>
struct Inter
{
void FuncA() { t.FuncA(); }
void FuncB() { t.FuncB(); }
T t;
};
// Always takes some sort of Inter<T>.
template<typename InterType>
struct Final
{
void CallFuncs()
{
// if( t.FuncA() exists and can …Run Code Online (Sandbox Code Playgroud) 我正在学习如何使用SFINAE.我正在尝试使用它来根据serialize()对象中函数的存在来选择函数实现.
这是我用来确定的代码,如果类型定义了serialize()函数:
template <typename T>
class HasSerialize {
private:
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
template <typename C> static no& test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
Run Code Online (Sandbox Code Playgroud)
但是,它似乎在GCC和Clang上给出了完全相同的结果.假设以下代码:
template<bool T>
class NVPtypeSerializer {
public:
template<typename C>
static xmlChar* serialize(C value) {
// serize() is not available
}
};
template<>
struct NVPtypeSerializer<true> {
public:
template<typename T>
static xmlChar* serialize(T value) {
return value.serialize();
}
};
Run Code Online (Sandbox Code Playgroud)
这被称为:
foo = …Run Code Online (Sandbox Code Playgroud) 在使用SFINAE编写模板专业化时,您经常会因为一个小的不存在的成员或函数而需要编写一个全新的特化.我想把这个选择打包成一个小的声明,比如orElse<T a,T b>.
小例子:
template<typename T> int get(T& v){
return orElse<v.get(),0>();
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?