我正在搞乱模板特化,我遇到了一个问题,试图根据使用的策略来专门构建构造函数.这是我试图开始工作的代码.
#include <cstdlib>
#include <ctime>
class DiePolicies {
public:
class RollOnConstruction { };
class CallMethod { };
};
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
template<unsigned sides = 6, typename RollPolicy = DiePolicies::RollOnConstruction>
class Die {
// policy type check
BOOST_STATIC_ASSERT(( boost::is_same<RollPolicy, DiePolicies::RollOnConstruction>::value ||
boost::is_same<RollPolicy, DiePolicies::CallMethod>::value ));
unsigned m_die;
unsigned random() { return rand() % sides; }
public:
Die();
void roll() { m_die = random(); }
operator unsigned () { return m_die + 1; }
};
template<unsigned sides>
Die<sides, DiePolicies::RollOnConstruction>::Die() : m_die(random()) { …Run Code Online (Sandbox Code Playgroud) 模板类的成员函数可以完全特化,例如
template<class A>
struct MyClass {
// Lots of other members
int foo();
};
template<class A>
MyClass<A>::foo() { return 42; }
template<>
MyClass<int>::foo() { return 0; }
Run Code Online (Sandbox Code Playgroud)
会编译没有问题。请注意,这foo()不是模板函数,因此这与模板函数专业化无关(我可以理解在那里不允许部分专业化,因为它与重载相结合会变得非常混乱)。在我看来,上面的代码只是以下模板类专业化的简写:
template<class A>
struct MyClass {
// Lots of other members
int foo();
};
template<class A>
MyClass<A>::foo() { return 42; }
template<>
struct MyClass<int> {
// Copy all the other members from MyClass<A>
int foo();
};
template<>
MyClass<int>::foo() { return 0; }
Run Code Online (Sandbox Code Playgroud)
这样对吗?
在这种情况下,我想知道为什么不允许使用类似速记的部分专业化,即为什么我不能写
template<class …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization member-functions class-template
#include <iostream>
template <typename T1, typename T2>
class B{
public:
void update(){ std::cerr<<__PRETTY_FUNCTION__<<std::endl; }
void func1(){ std::cerr<<__PRETTY_FUNCTION__<<std::endl; }
void func2(){ std::cerr<<__PRETTY_FUNCTION__<<std::endl; }
};
template <typename T1>
class B<T1, int>{
public:
void update(){ std::cerr<<__PRETTY_FUNCTION__<<"(specialization)"<<std::endl;}
};
int main(){
B<int, double> b1;
b1.update();
b1.func1();
B<int, int> b2;
b2.update();
//b2.func1();//there's no function 'func1' in B<int,int>
}
Run Code Online (Sandbox Code Playgroud)
我想专门update针对特定模板参数(数据类型)的函数。
所以我尝试专业化template class B,但似乎我必须再次实现整个成员函数。
由于专业化之间的其他成员完全相同,因此重新实现整个成员看起来很麻烦。
对于这种情况有什么解决方法吗?
我有以下课程:
template <class... T>
class thing {};
template <class T>
class container {
public:
container() {
std::cout << "normal constructor" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
我可以用container<int>这种方式为构造函数编写一个完整的特化:
template <>
container<int>::container() {
std::cout << "int constructor" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够为其定义类似的构造函数container<thing<T>>.我认为我试图写的是模板函数的部分特化(这是非法的.)这是我正在尝试的:
template <class T>
container<thing<T>>::container() {
}
Run Code Online (Sandbox Code Playgroud)
这不编译.
我不完全确定解决这个问题的正确方法是什么,以及模板类函数的重载和特化之间的界限越来越模糊.这可以简单地解决,还是需要type_traits(std::enable_if)?我怎么解决这个问题?
c++ templates partial-specialization template-specialization c++14
我只是在阅读 C++20 概念的例子。现在我正在尝试创建一个函数,该函数将打印出给定类型是否是哈希表或不使用与部分专业化混合的概念。但不幸的是它不起作用。
#include <iostream>
#include <string>
template<typename T>
concept Hashtable = requires(T a) {
{ std::hash<T>{}(a) } -> std::size_t;
};
struct Foo {};
template <typename T>
void Bar() {
std::cout << "Type T is not a hashtable" << std::endl;
}
template <Hashtable T>
void Bar<T> {
std::cout << "Type T is a hashtable" << std::endl;
}
int main()
{
Bar<Foo>();
Bar<std::string>();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用编译器版本 GCC HEAD 9.0.1,编译器标志是g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.69.0/gcc-head/include -std=gnu++2a "-fconcepts". 它给了我以下编译器错误:
prog.cc:18:6: error: template-id 'Bar<T>' …Run Code Online (Sandbox Code Playgroud) 我有一些模板化类类型,例如 A、B、C,如下所示:
template < typename T >
class A{};
template < typename T >
class B{};
template < typename T >
class C{};
Run Code Online (Sandbox Code Playgroud)
现在我想要一个函数,它通常接受任何类型,例如:
template < typename T>
void Func()
{
std::cout << "Default " << __PRETTY_FUNCTION__ << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
现在我想将该函数专门化为仅接受给定的模板类之一,例如:
template < typename T>
void Func<A<T>>()
{
std::cout << "All A Types " << __PRETTY_FUNCTION__ << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这是不允许的,因为它只是部分专业化。好的。
我认为concept可能有帮助,但感觉我想得太复杂了。我的解决方案是:
template < typename T, template <typename > typename OUTER >
bool Check;
template < typename INNER, template …Run Code Online (Sandbox Code Playgroud) 我是一名新的C++程序员,不久前我学习了Java和ANSI C,并决定试一试.
好吧,我喜欢C++,但我不喜欢迭代器的工作方式:
在java中,你可以将整个容器设为私有,并为它的迭代器实现一个getter函数,迭代器有一个方法hasNext(),它返回一个布尔值,具体取决于它是否已到达容器的末尾.
我发现在C++上做类似事情的唯一方法就是编写2个getter,iteratorBegin()然后iteratorEnd()返回一个对应于第一个和最后一个位置的interator,递增返回的迭代器iteratorBegin()并将其与之比较iteratorEnd(),允许我迭代容器直到最后一个已经达到了位置
但是,我想只使用一个getter方法,我想:"让我自己创建迭代器类"
到目前为止一切顺利,我已成功完成了套装和列表,但我似乎无法用地图制作它,这里的代码令我不安:(该类是在一个单独的.h中定义的,这称为customIterator的.cpp)
template<typename T, typename D>
const D& custIterator<T,D>::next()
{
const D& obj = (*it);
if(hasNext())
{
it++;
}
return obj;
}
//the above works fine
template<typename T, typename D>
const D& custIterator<map<T,D>,D>::next() //error in this line
{
D& obj = (*it).second;
if(hasNext())
{
it++;
}
return obj;
}
Run Code Online (Sandbox Code Playgroud)
在编译专用方法时,它说:错误:即使我#include <map>在文件顶部添加了'map'也未在此范围内声明
我正在使用带有代码块的gcc版本4.4.5(Debian 4.4.5-8)
拜托,我需要一些帮助.
感谢您的关注!
如果我删除模板特化部分(试图打印"测试2"的部分),代码编译很好,但我希望能够有一个特殊情况,运行一个看起来干净的外部用户不同的代码路径.
#include <iostream>
using namespace std;
struct SpecialType {};
template<typename A , typename B = SpecialType>
class Test
{
public:
class TestInner
{
public:
TestInner& operator* ();
};
};
template<typename A , typename B>
typename Test<A , B>::TestInner& Test<A , B>::TestInner::operator* ()
{
cout << "Test 1" << endl;
return *this;
}
// If the following is removed, everything compiles/works, but I want this alternate code path:
template<typename A>
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
{
cout << …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization specialization template-specialization
我正在编写一个矢量类,我希望它具有以下特征:
通过我提出的解决方案在下面找到这个简单的测试问题.我使用继承,因此Vector继承自Vector_base,它为所有向量提供了一个通用接口(纯虚拟).然后我定义了一个空类Vector,允许我使用部分特化来拥有不同的存储方案; 静态或动态.
这背后的想法是我只想让vector成为旧式静态数组的C++包装器.
我喜欢下面的实现.我想保留我想出的主界面.
我不喜欢的是sizeof(Vector3)= 32,当在C中时,三个双精度的矢量是24个字节.原因是虚拟表的额外8个字节.
我的问题:我可以以某种方式提出另一种设计,它将为我提供相同的接口,但矢量只有24个字节?
总结:
<double,n>)我可以使用像特征或政策这样的编程习语吗?我是新手,我不知道他们是否能提供解决方案.
找到我的小测试代码如下:
#include <iostream>
using namespace std;
#define TRACE0(a) cout << #a << endl; a;
#define TRACE1(a) cout << #a "=[" << a << "]" << endl;
enum alloc_type {Static,Dynamic};
template <class T>
class Vector_base{
public:
Vector_base(){}
virtual operator T*() = 0;
virtual T operator[](int i)const = 0;
virtual T& operator[](int i) = 0;
virtual int size() const = 0;
friend ostream& operator<<(ostream …Run Code Online (Sandbox Code Playgroud) 这个程序
#include <iostream>
template <int I>
struct A
{
A() { std::cout << "A<I>()\n"; }
};
template <int I>
struct A<I + 5>
{
A() { std::cout << "A<I + 5>()\n"; }
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
既不由gcc HEAD 10.0.0 20190也不由clang HEAD 10.0.0编译。
例如gcc编译器发出错误
prog.cc:10:8: error: template argument '(I + 5)' involves template parameter(s)
10 | struct A<I + 5>
| ^~~~~~~~
Run Code Online (Sandbox Code Playgroud)
是否存在错误的类模板局部专业化?